When you define an association, Sequelize automatically generates a join table for you. As an example:
Post.associate = function(models) {
Post.belongsTo(models.User, { as: "Author" });
Post.belongsTo(models.Company);
Post.belongsToMany(models.Topic, { through: "PostTopic" });
Post.belongsToMany(models.User, { through: "PostAction" });
Post.hasMany(models.Comment);
Post.hasMany(models.Image);
}
Here, Sequelize would generate “PostTopic” table. The table would be generated, but you would have limitations:
Sequelize doesn’t define any methods for this table. For example, if you tried to do:
models.PostTopic.count()
It won’t work, because Sequelize did not define the count method, because the PostTopic table was not explicitly defined.
If you need to add additional fields to the join table, you need to define a new model.
However, if you simply defined a “PostTopic” model, it doesn’t work, even though I think it should have.
There will be two differences from before:
Sequelize will create a new table called “PostTopics” (plural), instead of “PostTopic”.
It will also add a new “Id” field to this table, that does not exist in the original autogenerated join table.
This will confuse your database with 2 tables, namely “PostTopic” original, and “PostTopics”, and you will probably need to use a migration from the original join table to the new one or something. I haven’t tried this.
In order to remedy that I used the following work around.
'use strict';
module.exports = (sequelize, DataTypes) => {
const PostTopic = sequelize.define('PostTopic', {
}, {
freezeTableName: true,
tableName: 'PostTopic'
});
return PostTopic;
};
This defines the table as normal, but forces the singular name. By doing this, Sequelize finds that this table already exists, but also autogenerates the database methods that I needed. Tested to work. For the record we’re using PostgreSQL 10.x with Sequelize.