简体   繁体   中英

How to do a Many to Many relationship in Sequelize?

These are my models: Staff

const { DataTypes } = require('sequelize');
const sequelize = require('../sequelize')

const Staff = sequelize.define('Staff', {

name: {
    type: DataTypes.STRING,
    allowNull: false,
},
SSN: {
    type: DataTypes.INTEGER,
},
email:{
    type: DataTypes.STRING,
}
}, {
    timestamps: true
});
Staff.associate = function (models) {
    Staff.belongsToMany(models.Technology, {through: models.StaffTechnology});

};

module.exports = Staff;

Technology:

const { DataTypes } = require('sequelize');
const sequelize = require('../sequelize')


const Technology = sequelize.define('Technology', {
    name: {
        type: DataTypes.STRING,
        allowNull: false,
    },
    description: {
        type: DataTypes.STRING,

    }
}, {
    timestamps: true
});
Technology.associate = function (models) {
    Technology.belongsToMany(models.Staff, { through: models.StaffTechnology});

};
module.exports = Technology;

This will be the join table:

const { DataTypes } = require('sequelize');
const sequelize = require('../sequelize')
const Staff = require('../../database/models/staff.model');
const Technology = require('../../database/models/technology.model');


const StaffTechnology = sequelize.define('StaffTechnology', {
    experience: {
        type: DataTypes.INTEGER,
    },
    StaffID: {
        type: DataTypes.INTEGER,
        references: {
            model: Staff, 
            key: 'id'
        }
    },
    TechnologyID: {
        type: DataTypes.INTEGER,
        references: {
            model: Technology,
            key: 'id'
        }
    },
}, {
    timestamps: true
});
StaffTechnology.associate = function (models) {
      //StaffTechnology.hasMany(models.Staff, { foreignKey: 'StaffID' });
      //StaffTechnology.hasMany(models.Technology, { foreignKey: 'TechnologyID' });
};

module.exports = StaffTechnology

Right now I cant do a Staff.findAll({include:Technology}), since it give me an error saying that Staff and Technology are not associated, but I saw Sequelize documentation, and I saw a very similar example working. What I want is the posibility to return All Staffs with their technologies, Staff can have many technologies, and Technologies can belong to Many Staffs, but in reality they are connected through StaffTechnology join table.

You need to declare the associations inside of your index.js (or where you initialize your DB). You can either do it manually by declaring the associations directly by requiring the models and doing

Model1.association(Model2, {
  through: "JoinTable"
}

Model2.association(Model1, {
  through: "JoinTable"
}

Or do it programmatically (If you are already using that approach to initialize your DB):

'use strict'
 
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const config = {
  "username": "root",
  "password": "YOUR ROOT PASSWORD HERE",
  "database": "YOUR DATABASE NAME HERE",
  "host": "127.0.0.1",
  "dialect": "mysql"
}
const db = {}
 
let sequelize = new Sequelize(config.database, config.username, config.password, config);
 
fs.readdirSync(__dirname)
  .filter(file => {
    return (file.indexOf('.') !== 0)
    && (file !== basename)
    && (file.slice(-3) === '.js');
  })
  .forEach(file => {
    const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
    db[model.name] = model;
  });
 
Object.keys(db).forEach(modelName => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});
 
db.sequelize = sequelize;
db.Sequelize = Sequelize;
 
module.exports = db;

^ This code does both the initialization and the associations in one. You need to make sure that your model files and the initialization file are in the same folder.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM