NodeJS 函数Magic Sequelize不存在

1qczuiv0  于 2023-10-17  发布在  Node.js
关注(0)|答案(1)|浏览(99)

我是TypeScript的初学者,最近开始学习Sequelize ORM模型。我已经用普通的JavaScript做了几个Sequelize项目,但我决定给予一个使用TypeScript的尝试。我在这个问题上已经纠结了好几天了。
我是巴西人,所以有些变量可能是葡萄牙语。如果你有任何与此相关的问题,我可以在评论中澄清。
操作系统:Win10
问题:我的PostgreSQL数据库有3个实体:我已经为用户和电影创建了路由、控制器和服务。但是,当我尝试向我的用户添加电影时,它给我一个错误,说Sequelize的关联功能不存在。
错误:[{"resource": "/c:/Users/pc/Documents/GitHub/trybeJava/EstudosTs/projetoSequelize/src/service/UsuarioFilmeService.ts", "owner": "typescript", "code": "2339", "severity": 8, "message": "Property 'addFilme' does not exist on type 'Usuario'.", "source": "ts", "startLineNumber": 25, "startColumn": 21, "endLineNumber": 25, "endColumn": 29 }]
错误消息:Property 'addFilme' does not exist on type 'Usuario'.
我相信我的数据库配置文件是正确的,因为用户和电影的端点正在成功地创建和检索数据。问题似乎出在最后实现的路由API/userFilme上。
Server.ts(应用程序配置)

import express from 'express'
import cors from 'cors'
import userRoute from './routes/UserRoute'
import filmeRoute from './routes/FilmeRoute'
import userFilmeRoute from './routes/UserFilmeRoute'
import database from './database'

class App {
  public express: express.Application

  public constructor () {
    this.express = express()
    this.index()
  }

  private index (): void {
    this.express.use(express.json())
    this.express.use(cors())
    this.express.listen(3333, () => {
      console.log('rodando')
    })
    this.route()
    this.dataBase()
  }

  private middleware (): void {
  }

  private dataBase (): void {
    database.getConection()
  }

  private route (): void {
    this.express.use('/api/user', userRoute)
    this.express.use('/api/filme', filmeRoute)

//Here
    this.express.use('/api/userFilme', userFilmeRoute)
  }
}

export default new App()

该路由又将请求发送到UserFilmController,后者有一个方法来创建用户和电影之间的关系。

public async addMovieToUser (): Promise<ResponseDto<UserMoviesFavorite>> {
    const sequelize = Connection.getConection()
    const transaction = await sequelize.transaction()

    try {
      const usuario = await Usuario.findByPk(this.idUser)
      const filme = await Filme.findByPk(this.idFilme)
      // bem aqui o erro
      await usuario.addFilme(filme, { transaction })

      await transaction.commit()

      return {
        status: 200,
        message: 'Filme adcionado como favorito'
      }
    } catch (error) {
      await transaction.rollback()

      return {
        status: 500,
        message: error

      }
    }
  }
}

我添加电影的那一行根本不存在,因为在JavaScript中,它像这样工作得很好。下面,我将提供我的模型和迁移以供参考。

模型martario.ts

import { Model, DataTypes, type Sequelize } from 'sequelize'

class Usuario extends Model {
  static associate (models): void {
    this.belongsToMany(models.Filme, { foreignKey: 'id_usuario', through: 'usuarios_filmes', as: 'filmes' })
  }

  static initTable (connection: Sequelize): void {
    this.init(
      {
        nome: DataTypes.STRING,
        idade: DataTypes.INTEGER
      },
      {
        sequelize: connection,
        modelName: 'Usuario',
        tableName: 'usuarios'
      }
    )
  }
}

export default Usuario

模型Filme.ts

import { Model, DataTypes, type Sequelize } from 'sequelize'

class Filme extends Model {
  public id!: number
  public titulo!: string
  public diretor!: string
  public nota!: number

  static associate (models): void {
    this.belongsToMany(models.Usuario, { foreignKey: 'id_filme', through: 'usuarios_filmes', as: 'usuarios' })
  }

  static initTable (connection: Sequelize): void {
    this.init(
      {
        titulo: DataTypes.STRING,
        diretor: DataTypes.STRING,
        nota: DataTypes.INTEGER
      },
      {
        sequelize: connection,
        modelName: 'Filme',
        tableName: 'filmes'
      }
    )
  }
}

export default Filme

Migration usuarios_filmes

'use strict'

/\*\* @type {import('sequelize-cli').Migration} \*/
module.exports = {
up: async (queryInterface, Sequelize) =\> {
await queryInterface.createTable('usuarios_filmes', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
id_usuario: {
type: Sequelize.INTEGER,
references: {
model: 'usuarios',
key: 'id'
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
allowNull: false
},
id_filme: {
type: Sequelize.INTEGER,
references: {
model: 'filmes',
key: 'id'
},
onUpdate: 'CASCADE',
onDelete: 'CASCADE',
allowNull: false
},
created_at: {
allowNull: false,
type: Sequelize.DATE
},
updated_at: {
allowNull: false,
type: Sequelize.DATE
}
})
},

down: async (queryInterface, Sequelize) =\> {
await queryInterface.dropTable('usuarios_filmes')
}
}

我想澄清的是,当调用addFilme方法时,应该向usuarios_filmes表添加一个新行。例如,如果我传递1和1,这意味着用户1喜欢电影1,这应该反映在表中。

omtl5h9j

omtl5h9j1#

不知道这是否能解决你的问题,但它帮助了我在类似的情况。
我有两个模型,UserProduct,具有一对多的关联。我想使用一个req.user. req产品魔术方法,它在JS中有效,但在TS中无效。为了让它工作,我必须在User类中实现方法名称。
我把我的User模型贴给你,这可能会更好地阐明我的意思:

import {
  CreationOptional,
  DataTypes,
  InferAttributes,
  InferCreationAttributes,
  Model,
  Association,
  HasManyGetAssociationsMixin,
  HasManyCreateAssociationMixin,
} from "sequelize";
import sequelize from "../util/database";
import Product from "./product";

class User extends Model<InferAttributes<User>, InferCreationAttributes<User>> {
  declare id: CreationOptional<number>;
  declare username: string;
  declare email: string;

  public getProducts!: HasManyGetAssociationsMixin<Product>;
  public createProduct!: HasManyCreateAssociationMixin<Product>;

  public readonly products?: Product[];

  public static associations: {
    products: Association<User, Product>;
  };
}

User.init(
  {
    id: {
      type: DataTypes.INTEGER,
      autoIncrement: true,
      allowNull: false,
      primaryKey: true,
    },
    username: {
      type: DataTypes.STRING(120),
      allowNull: false,
    },
    email: {
      type: DataTypes.STRING(255),
      allowNull: false,
    },
  },
  {
    sequelize,
    tableName: "users",
    paranoid: true,
    deletedAt: "destroyTime",
  }
);

export default User;

正如您所看到的,在第20行中,我必须手动添加由sequelize创建的siteProduct方法,但我必须显式地让TS知道它的存在。
我发现这个解决方案阅读的问题使here

相关问题