I'm new in this sequelize things. I try to associate model between Users and Permissions through UserPermissions using belongsToMany, and this is my code.
-- users.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;
};
According to sequelize docs about belongsToMany in here, belongsToMany will create a new model that link to whatever model that you join, right.
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
But when I try that and migrate it using sequelize-cli
, I didn't see any join table that had been created. The Users Table is created, The Permissions Table is created, but UserPermissions Table is not created. Did I miss some thing in here? or there is something wrong with my code?
I'm using postgres
dialect, "pg": "^6.4.0"
and "sequelize": "^4.3.1"
Oh ya, I'm really sorry about my english, I'm not really good in english.
To answer your question (many years later):
You were likely told by the documentation to do this to create a join table:
In your User associations:
User.belongsToMany(models.Permission, {
through: 'UserPermissions',
foreignKey: 'user_id'
});
In your Permission associations:
Permission.belongsToMany(models.User, {
through: 'UserPermissions',
foreignKey: 'permission_id'
});
The portion of the process not mentioned in the documentation is how to actually create this table that you use in the database. To create the table used by these functions in the database, create a migration with the following code:
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')
}
}
Using the Sequelize CLI will generate most of this code for you. Note that the model
object property under references
is the table name in postgres (well, this is what worked for me).
EDIT:
Also note that the through
property should be a model, so:
through: models.UserPermission
and create the relevant model.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With