I'm having trouble setting an attribute on a junction table.
I have a Many-to-Many association defined between two models UserModel
and HangModel
, through a custom table HangUsers
.
const HangModel = rootRequire('/models/Hang');
const UserModel = rootRequire('/models/User');
const HangUsers = database.define('HangUsers', {
id: {
type: Sequelize.INTEGER(10).UNSIGNED,
primaryKey: true,
autoIncrement: true,
},
hangId: {
type: Sequelize.INTEGER(10).UNSIGNED,
references: {
model: HangModel,
key: 'id',
},
},
userId: {
type: Sequelize.INTEGER(10).UNSIGNED,
references: {
model: UserModel,
key: 'id',
},
},
rsvp: {
type: Sequelize.STRING,
allowNull: false,
validate: {
isIn: {
args: [ 'pending', 'joined' ],
msg: 'The rsvp provided is invalid',
},
},
},
});
UserModel.hasMany(HangUsers, { as: 'invitations' });
HangModel.hasMany(HangUsers, { as: 'invites' });
UserModel.belongsToMany(HangModel, { through: HangUsers });
HangModel.belongsToMany(UserModel, { through: HangUsers });
The through table has a column rsvp
, that I'm trying to populate when I add users to a hang:
const hang = await HangModel.create();
await hang.addUser(user, { through: { rvsp: 'joined' } });
However, I'm getting an error:
AggregateError
at recursiveBulkCreate (/Users/sgarza62/ditto-app/api/node_modules/sequelize/lib/model.js:2600:17)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async Function.bulkCreate (/Users/sgarza62/ditto-app/api/node_modules/sequelize/lib/model.js:2824:12)
at async Promise.all (index 0)
at async BelongsToMany.add (/Users/sgarza62/ditto-app/api/node_modules/sequelize/lib/associations/belongs-to-many.js:740:30)
at async /Users/sgarza62/ditto-app/api/routes/hangs.js:121:3 {
name: 'AggregateError',
errors: [
BulkRecordError [SequelizeBulkRecordError]: notNull Violation: HangUsers.rsvp cannot be null
at /Users/sgarza62/ditto-app/api/node_modules/sequelize/lib/model.js:2594:25
at processTicksAndRejections (internal/process/task_queues.js:97:5) {
name: 'SequelizeBulkRecordError',
errors: [ValidationError],
record: [HangUsers]
}
]
}
When I allow null on the rsvp column, the HangUsers
row is created, but the rsvp value is NULL
.
It seems the { through: { rsvp: 'joined' } }
parameter is being ignored.
I've done this all according to the BelongsToMany docs and the Advanced M:N Associations docs, where it says:
However, defining the model by ourselves has several advantages. We can, for example, define more columns on our through table:
const User_Profile = sequelize.define('User_Profile', { selfGranted: DataTypes.BOOLEAN }, { timestamps: false }); User.belongsToMany(Profile, { through: User_Profile }); Profile.belongsToMany(User, { through: User_Profile });
With this, we can now track an extra information at the through table, namely the selfGranted boolean. For example, when calling the user.addProfile() we can pass values for the extra columns using the through option.
Example:
const amidala = await User.create({ username: 'p4dm3', points: 1000 }); const queen = await Profile.create({ name: 'Queen' }); await amidala.addProfile(queen, { through: { selfGranted: false } }); const result = await User.findOne({ where: { username: 'p4dm3' }, include: Profile }); console.log(result);
from Adding Attributes on a Join Table in Sequelize
No comments:
Post a Comment