javascript - sequelize 上的 belongsToMany 是否会自动创建新的连接表?

标签 javascript node.js associations sequelize.js

我是这个 Sequelize 的新手。我尝试使用 belongsToMany 通过 UserPermissions 在用户和权限之间关联模型,这是我的代码。

-- 用户.js

const bcrypt = require('bcrypt');
const config = require('../config/general');

module.exports = (sequelize, DataTypes) => {
    const User = sequelize.define('User', {
        email: {
            type: DataTypes.STRING,
            allowNull: false,
            unique: true,
            validate: {
                isLowercase: true,
                notEmpty: true,
                isEmail: true
            }
        },
        username: {
            type: DataTypes.STRING,
            allowNull: false,
            unique: true,
            validate: {
                isLowercase: true,
                notEmpty: true,
                min: 3
            }
        },
        salt: {
            type: DataTypes.STRING,
            allowNull: true
        },
        password: {
            type: DataTypes.STRING,
            allowNull: false,
            validate: {
                notEmpty: true
            }
        },
    }, {
        underscored: true,
        classMethods: {
            associate: (models) => {
                User.belongsToMany(models.Permission, {
                    through: 'UserPermissions', 
                    foreignKey: 'user_id'
                });
            },
            validPassword: (password, passwd, done) => {
                const tmppass = password + config.secret;
                bcrypt.compare(tmppass, passwd, (err, isMatch) => {
                    if (err) return done(err);
                    return done(null, isMatch);
                });
            }
        }
    });

    User.beforeCreate( (user, option, done) => {
        bcrypt.genSalt(SALT_WORK_FACTOR, (err, salt) => {
            if (err) return done(err);
            const tmppass = user.password + config.secret;
            bcrypt.hash(tmppass, salt, (err, hash) => {
                if (err) return done(err);
                user.salt       = salt;
                user.password   = hash;
                return done(null, user);
            });
        });
    });

    return User;
};

-- permissions.js

module.exports = (sequelize, DataTypes) => {
    const Permission = sequelize.define('Permission', {
        name: {
            type: DataTypes.STRING,
            allowNull: false,
            validate: {
                notEmpty: true
            }
        },
        slug: {
            type: DataTypes.STRING,
            validate: {
                isLowercase: true
            }
        },
        description: {
            type: DataTypes.TEXT
        }
    }, {
        underscored: true,
        classMethods: {
            associate: (models) => {
                Permission.belongsToMany(models.User, { 
                    through: 'UserPermissions', 
                    foreignKey: 'permission_id'
                });
            }
        }
    });

    return Permission;
};

根据 here 中关于 belongsToMany 的 Sequelize 文档, belongsToMany 将创建一个新模型,链接到您加入的任何模型,对吧。

This will create a new model called UserProject with the equivalent foreign keys projectId and userId. Whether the attributes are camelcase or not depends on the two models joined by the table (in this case User and Project). Sequelize Belongs-To-Many

但是当我尝试这样做并使用 sequelize-cli 迁移它时,我没有看到任何已创建的连接表。 Users 表已创建,Permissions 表已创建,但 UserPermissions 表未创建。我在这里错过了什么吗?还是我的代码有问题?

我正在使用 postgres 方言,"pg": "^6.4.0""sequelize": "^4.3.1"

哦,是的,我真的很抱歉我的英语不好,我的英语不是很好。

最佳答案

回答你的问题(多年后):

文档可能告诉您执行此操作以创建连接表:

在您的用户关联中:

User.belongsToMany(models.Permission, {
                    through: 'UserPermissions', 
                    foreignKey: 'user_id'
                });

在您的权限关联中:

Permission.belongsToMany(models.User, { 
                    through: 'UserPermissions', 
                    foreignKey: 'permission_id'
                });

文档中未提及的过程部分是如何实际创建您在数据库中使用的表。要在数据库中创建这些函数使用的表,请使用以下代码创建迁移:

module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('UserPermissions', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      permission_id: {
        type: Sequelize.INTEGER,
        references: {
          model: 'Permissions',
          key: 'id',
          as: 'permission_id'
        }
      },
      user_id: {
        type: Sequelize.INTEGER,
        references: {
          model: 'Users',
          key: 'id',
          as: 'user_id'
        }
      },
      createdAd: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    })
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('UserPermissions')
  }
}

使用 Sequelize CLI 将为您生成大部分代码。请注意,references 下的 model 对象属性是 postgres 中的表名(好吧,这对我有用)。

编辑:

另请注意,through 属性应该是一个模型,因此:

through: models.UserPermission

并创建相关模型。

关于javascript - sequelize 上的 belongsToMany 是否会自动创建新的连接表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45050743/

相关文章:

ruby-on-rails - 无法在 Rails 3 中找到 has_many 的逆关联

javascript - 如何在 anchor 标记悬停时添加类

javascript - 当在 durandal/knockout 中取消(关闭)模式时通知主机页面

javascript - 使用 css/javascript 迭代隐藏 html 表的最后一列

javascript - 回调 node.js 中变量的扩展

javascript - babel-node 无法在 node_modules 中要求 jsx 文件

node.js - Firestore函数: handle map value

sql - 通过模型关联对nodejs进行序列化

javascript - 如何在angularjs中检查字符串是否为空

ruby-on-rails - 如何在Rails表单belongs_to关联中指定联接条件?