Create multiple rows in many to many relationship between same models in Sequelize
Sequelize is very popular ORM compatible with multi dialect for Node.js
It enables the developer to create migrations, seeders and models with many relation types. It also has a CLI which makes the work even easier and faster.
Long story short, once I created two models with many to many relationship. The business logic required me to allow having multiple records containing the same models foreign keys in the pivot table like this:
id | companyId | userId | createdAt | updatedAt |
1 | 5 | 20 | 2023-01-01 10:20:30 | 2023-01-01 10:20:30 |
2 | 5 | 20 | 2023-01-02 10:20:30 | 2023-01-02 10:20:30 |
In Sequelize, we can create the many to many relationship in models this way:
Company.belongsToMany(User, { through: 'Views', foreignKey: 'companyId', as: 'View' })
User.belongsToMany(Company, { through: 'Views', foreignKey: 'userId', as: 'View' })
After creating the relationship, Sequelize automatically creates special methods on the fly helping us to manage the relationship between models. please refer to this link to get more details
https://sequelize.org/docs/v6/core-concepts/assocs/#special-methodsmixins-added-to-instances
The same applies from User to Company as well
The Sequelize add method is the method that creates a connection between the models in the pivot table like this:
company.addView(userId)
The method initially performs a query, checking if a connection is already exists in the pivot table and in that case, it does not create a new record
While that may not be the case you want, do not forget that this constraint is not on the database level but on the ORM level, so the problem can be solved if you make a manual insertion or if the pivot table was representing a model for example.
In Sequelize this happens because they are making a comparison using the === operator between what they got from the database and what you as a developer passing. This test will fail when you pass an instance or an ID as an integer, so the solution is to pass the same ID but as a string like this.
company.addView(String(userId))
This will fail the comparison and will enable you adding another row using the same IDs.
Thanks to @ubaeida.