NodeJs: Sequelize (версия - 5+) N: M ассоциация не работает - PullRequest
0 голосов
/ 03 марта 2020

У меня возникла проблема, связанная с ассоциацией N: M с продолжением. Я пробовал с 5 различными подходами (см. В разделе кода User.ts & Batch.ts [1] / [2] ...). Ниже приведены сведения об ошибке и коде.

Используемая версия - "sequelize": "^ 5.21.5"

Ссылка: https://sequelize.org/v5/manual/associations.html#belongs-ко-многим-ассоциациям

Мне нужно ваше руководство, чтобы исправить проблему.

Получение ниже Ошибка

/home/priyabrata/projects/node_backend_new/node_modules/sequelize/lib/associations/mixin.js:49
      throw new Error(`${this.name}.belongsToMany called with something that's not a subclass of Sequelize.Model`);
      ^

Error: Batch.belongsToMany called with something that's not a subclass of Sequelize.Model
    at Function.belongsToMany (/home/priyabrata/projects/node_backend_new/node_modules/sequelize/lib/associations/mixin.js:49:13)

Найти ниже код

/ /models/database.ts

import {Sequelize} from 'sequelize';
import Config from "config";
export const database = new Sequelize(
                            Config.get("DB.NAME"), 
                            Config.get("DB.USER"), 
                            Config.get("DB.PASS"),
                            {
                                host: Config.get("DB.HOST"),
                                port: 3306,
                                dialect: 'mysql'
                            });

// models / User.ts

import { Model, DataTypes } from "sequelize";
import { database } from "./database";
import { Batch } from "./Batch"
import { UserBatch } from "./UserBatch";

export class User extends Model {

}

export interface UserInterface {
  id: number;
  firstname: string;
  lastname: string;
}

User.init(
  {
    id: {
      type: DataTypes.INTEGER.UNSIGNED,
      autoIncrement: true,
      primaryKey: true,
      allowNull: false
    },
    firstname: {
      type: DataTypes.STRING(100),
      allowNull: false,
      defaultValue: ''
    },
    lastname: {
      type: DataTypes.STRING(100),
      allowNull: false,
      defaultValue: ''
    }
  },
  {
    underscored: true,
    tableName: "user",
    collate: "utf8mb4_unicode_ci",
    charset : "utf8mb4",
    engine : "InnoDB",
    sequelize: database, // this bit is important
    timestamps: false
  }
);



//[1] - Not working
// User.belongsToMany(Batch, {through:{model:UserBatch}, foreignKey:"user_id"});

//[2] - Not working
// User.belongsToMany(Batch, {through:{model:UserBatch}, foreignKey:"id"});

//[3] - Not working
//User.belongsToMany(Batch, {through:{model:UserBatch}, foreignKey:"id", otherKey: "user_id"});

//[4] - Not working
// User.belongsToMany(Batch, {through:'user_batch', foreignKey:"id"});

//[5] - Not working
// User.belongsToMany(Batch, {through:'user_batch', foreignKey:"id", otherKey: "user_id"});

// Below line will create table based on the above defination
// User.sync({ force: true }).then(() => console.log("User table created"));

// models / Batch.ts

import { Model, DataTypes } from "sequelize";
import { database } from "./database";
import { User } from "./User"
import { UserBatch } from "./UserBatch"

export class Batch extends Model {
}

export interface BatchInterface {
  id: number;
  name: string;
}


Batch.init(
  {
    id: {
      type: DataTypes.INTEGER.UNSIGNED,
      autoIncrement: true,
      primaryKey: true,
      allowNull: false
    },
    name: {
      type: DataTypes.STRING(100),
      allowNull: false,
      defaultValue: ''
    }
  },  {
    underscored: true,
    tableName: "batch",
    collate: "utf8mb4_unicode_ci",
    charset : "utf8mb4",
    engine : "InnoDB",
    sequelize: database, // this bit is important
    timestamps: false
  }
);

//[1] - Not working
// Batch.belongsToMany(User, {through:{model: UserBatch}, foreignKey:"batch_id"});

//[2] - Not working
// Batch.belongsToMany(User, {through:{model: UserBatch}, foreignKey:"id"});

//[3] - Not working
//Batch.belongsToMany(User, {through:{model: UserBatch}, foreignKey:"id", otherKey: "batch_id"});

//[4] - Not working
// Batch.belongsToMany(User, {through:'user_batch', foreignKey:"id"});

//[5] - Not working
// Batch.belongsToMany(User, {through:'user_batch', foreignKey:"id", otherKey: "batch_id"});

// Below line will create table based on the above defination
// Batch.sync({ force: true }).then(() => console.log("batch table created"));

// models /UserBatch.ts

import { Model, DataTypes } from "sequelize";
import { database } from "./database";

export class UserBatch extends Model {

}

export interface UserBatchInterface {
  user_id: number;
  batch_id: number;
}

UserBatch.init(
  {
    user_id: {
      type: DataTypes.INTEGER.UNSIGNED,
      allowNull: false
    },
    batch_id: {
      type: DataTypes.INTEGER.UNSIGNED,
      allowNull: false
    }
  },  {
    underscored: true,
    tableName: "user_batch",
    collate: "utf8mb4_unicode_ci",
    charset : "utf8mb4",
    engine : "InnoDB",
    sequelize: database, // this bit is important
    timestamps: false
  }
);

// Below line will create table based on the above defination
// UserBatch.sync({ force: true }).then(() => console.log("user_batch table created"));

Ответы [ 2 ]

0 голосов
/ 04 марта 2020

У меня есть решение, и оно работает нормально.

Я удалил эту строку Batch.belongsToMany(User, {through:{model: UserBatch}, sourceKey:"id", foreignKey: "batch_id"}); из models/Batch.ts и добавил к models/User.ts.

User.belongsToMany(Batch, {through:{model:UserBatch}, sourceKey:"id", foreignKey: "user_id"});
Batch.belongsToMany(User, {through:{model: UserBatch}, sourceKey:"id", foreignKey: "batch_id"});

Пожалуйста, найдите полный код //models/User.ts

import { Model, DataTypes } from "sequelize";
import { database } from "./database";
import { Batch } from "./Batch"
import { UserBatch } from "./UserBatch";

export class User extends Model {

}

export interface UserInterface {
  id: number;
  firstname: string;
  lastname: string;
}

User.init(
  {
    id: {
      type: DataTypes.INTEGER.UNSIGNED,
      autoIncrement: true,
      primaryKey: true,
      allowNull: false
    },
    firstname: {
      type: DataTypes.STRING(100),
      allowNull: false,
      defaultValue: ''
    },
    lastname: {
      type: DataTypes.STRING(100),
      allowNull: false,
      defaultValue: ''
    }
  },
  {
    underscored: true,
    tableName: "user",
    collate: "utf8mb4_unicode_ci",
    charset : "utf8mb4",
    engine : "InnoDB",
    sequelize: database, // this bit is important
    timestamps: false
  }
);

User.belongsToMany(Batch, {through:{model:UserBatch}, sourceKey:"id", foreignKey: "user_id"});
Batch.belongsToMany(User, {through:{model: UserBatch}, sourceKey:"id", foreignKey: "batch_id"});

// Below line will create table based on the above defination
// User.sync({ force: true }).then(() => console.log("User table created"));

0 голосов
/ 04 марта 2020

Вы запускаете что-то подобное где-нибудь ?? Похоже, вы используете классы, а не секвелирование моделей ... отсюда ошибка "вызвана чем-то, что не является подклассом Sequelize.Model"

import { Sequelize } from 'sequelize';
import database from 'wherever that is exported';

const models = {
  User: database.import('path to where this class is'),
  UserBatch : database.import('path to where this class is'),
  Batch : database.import('path to where this class is'),
};

Object.keys(models).forEach((modelName) => {
  if ('associate' in models[modelName]) {
    models[modelName].associate(models);
  }
});

models.database= database;
models.Sequelize = Sequelize;

export default models;

Тогда в каждом классе вы можете иметь функцию, которая выглядит следующим образом: что код выше использует для инициализации ваших классов

User.associate = function (models) {
    models.User.belongsToMany(models.Batch, { through: models.UserBatch, as: 'batch', foreignKey: 'user_id' });    
  };

я понимаю, что использовал javascript и синтаксис diff, но идея та же

...