Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

sequelize.js - Is it correct the way to associate Models using Sequelize?

I create a relation N:N with the tables Users and Roles, generating a third table UserRole. Running a findAllin this relation I receive a message which SequelizeEagerLoadingError: UserRole is not associated to User!

This is how I define the models:

User:

const { Model } = require("sequelize");

module.exports = (sequelize, DataTypes) => {
    class User extends Model { };

    User.associate = (models) => {
        User.belongsToMany(models.Role, { through: models.UserRole });
    }

    User.init({
        username: DataTypes.STRING,
        password: DataTypes.STRING,
    }, { sequelize, modelName: "User" })

    return User;
}

Roles:

const { Model } = require("sequelize");

module.exports = (sequelize, DataTypes) => {
    class Role extends Model { }

    Role.associate = (models) => {
        Role.belongsToMany(models.User, { through: models.UserRole });
    };

    Role.init({
        name: DataTypes.STRING
    }, { sequelize, modelName: 'Role' });

    return Role
}

UserRole:

const { Model } = require("sequelize");

module.exports = (sequelize, DataTypes, models) => {
    class UserRole extends Model { }

    UserRole.init({
        user_id: {
            type: DataTypes.INTEGER,
            references: {
                model: Model.User,
                key: 'id'
            }
        },
        role_id: {
            type: DataTypes.INTEGER,
            references: {
                model: Model.Role,
                key: 'id'
            }
        }
    }, { sequelize, modelName: "UserRole" });

    return UserRole
}
question from:https://stackoverflow.com/questions/66052888/is-it-correct-the-way-to-associate-models-using-sequelize

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is an example that works

const { Model, Sequelize } = require('sequelize')

/**
 * Models
 */

// initModels it is like array of all your module.exports
const initModels = [
  // NOTE: no need to pass models here, only sequelize instance and DataTypes
  (sequelize, DataTypes) => {
    class User extends Model {}

    User.associate = (models) => {
      User.belongsToMany(models.Role, { through: models.UserRole, foreignKey: 'role_id' })
    }

    User.init(
      {
        username: DataTypes.STRING,
        password: DataTypes.STRING,
      },
      { sequelize, modelName: 'User', underscored: true }
    )

    return User
  },
  (sequelize, DataTypes) => {
    class Role extends Model {}

    Role.associate = (models) => {
      Role.belongsToMany(models.User, { through: models.UserRole, foreignKey: 'user_id' })
    }

    Role.init(
      {
        name: DataTypes.STRING,
      },
      {
        sequelize,
        modelName: 'Role', // Here is where you have the problem in your example, same for the Role model definition below
        underscored: true
      }
    )

    return Role
  },
  (sequelize, DataTypes) => {
    class UserRole extends Model {}

    UserRole.init(
      {}, // NOTE: you do not need to specify columns here they will be automaticaly created them (unless you are using DB migrations instead of `.sync()`)
      { sequelize, modelName: 'UserRole', timestamps: false, underscored: true }
    )

    return UserRole
  }
];

/**
 * Queries
 */

(async () => {
  try {
    const models = {}
    // NOTE: you migth need to change the connection options to run this example
    const sequelize = new Sequelize(
      'postgres://postgres:root@localhost:5413/sequelize_examples'
    )
    // init models
    initModels.forEach((initFn) => {
      const model = initFn(sequelize, Sequelize.DataTypes)
      models[model.name] = model
    })
    Object.keys(models).forEach(modelName => {
      if (models[modelName].associate) {
        models[modelName].associate(models);
      }
    });


    await sequelize.sync({ force: true })

    const adminRole = await models.Role.create({ name: 'Admin' })
    const managerRole = await models.Role.create({ name: 'Manager' })
    const admin = await models.User.create({ username: 'admin', password: 'secure' })
    await admin.setRoles([adminRole, managerRole])
    const userRoles = await models.UserRole.findAll()
    console.log(userRoles.map(userRole => userRole.toJSON()))

    await sequelize.close()
    console.log('DONE')
    process.exit(0)
  } catch (err) {
    console.error(err)
    process.exit(1)
  }
})()

Also, you can clone and run it by yourself using this repository https://github.com/dmshvetsov/sequelize-examples/blob/main/examples/many-to-many-association/index.js


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...