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

    Defining through is required. Sequelize would previously attempt to autogenerate names but that would not always lead to the most logical setups.

    This will add methods getUsers, setUsers, addUser,addUsers to Project, and getProjects, setProjects, addProject, and addProjects to User.

    1. User.belongsToMany(Project, { as: 'Tasks', through: 'worker_tasks', foreignKey: 'userId' })
    2. Project.belongsToMany(User, { as: 'Workers', through: 'worker_tasks', foreignKey: 'projectId' })

    foreignKey will allow you to set source model key in the through relation.otherKey will allow you to set target model key in the through relation.

    1. User.belongsToMany(Project, { as: 'Tasks', through: 'worker_tasks', foreignKey: 'userId', otherKey: 'projectId'})

    Of course you can also define self references with belongsToMany:

    Source and target keys

    If you want to create a belongs to many relationship that does not use the default primary key some setup work is required.You must set the sourceKey (optionally targetKey) appropriately for the two ends of the belongs to many. Further you must also ensure you have appropriate indexes created on your relationships. For example:

    1. const User = this.sequelize.define('User', {
    2. id: {
    3. type: DataTypes.UUID,
    4. allowNull: false,
    5. primaryKey: true,
    6. defaultValue: DataTypes.UUIDV4,
    7. field: 'user_id'
    8. },
    9. userSecondId: {
    10. type: DataTypes.UUID,
    11. allowNull: false,
    12. defaultValue: DataTypes.UUIDV4,
    13. field: 'user_second_id'
    14. }
    15. }, {
    16. tableName: 'tbl_user',
    17. indexes: [
    18. {
    19. unique: true,
    20. fields: ['user_second_id']
    21. ]
    22. });
    23. const Group = this.sequelize.define('Group', {
    24. type: DataTypes.UUID,
    25. allowNull: false,
    26. primaryKey: true,
    27. defaultValue: DataTypes.UUIDV4,
    28. field: 'group_id'
    29. },
    30. groupSecondId: {
    31. type: DataTypes.UUID,
    32. allowNull: false,
    33. defaultValue: DataTypes.UUIDV4,
    34. field: 'group_second_id'
    35. }
    36. }, {
    37. tableName: 'tbl_group',
    38. indexes: [
    39. {
    40. unique: true,
    41. fields: ['group_second_id']
    42. }
    43. ]
    44. });
    45. User.belongsToMany(Group, {
    46. through: 'usergroups',
    47. sourceKey: 'userSecondId'
    48. });
    49. Group.belongsToMany(User, {
    50. sourceKey: 'groupSecondId'
    1. class User extends Model {}
    2. User.init({}, { sequelize, modelName: 'user' })
    3. class Project extends Model {}
    4. Project.init({}, { sequelize, modelName: 'project' })
    5. class UserProjects extends Model {}
    6. UserProjects.init({
    7. status: DataTypes.STRING
    8. }, { sequelize, modelName: 'userProjects' })
    9. User.belongsToMany(Project, { through: UserProjects })
    10. Project.belongsToMany(User, { through: UserProjects })

    To add a new project to a user and set its status, you pass extra options.through to the setter, which contains the attributes for the join table

    By default the code above will add projectId and userId to the UserProjects table, and remove any previously defined primary key attribute - the table will be uniquely identified by the combination of the keys of the two tables, and there is no reason to have other PK columns. To enforce a primary key on the UserProjects model you can add it manually.

    1. class UserProjects extends Model {}
    2. UserProjects.init({
    3. id: {
    4. type: Sequelize.INTEGER,
    5. primaryKey: true,
    6. autoIncrement: true
    7. },
    8. status: DataTypes.STRING
    9. }, { sequelize, modelName: 'userProjects' })

    With Belongs-To-Many you can query based on through relation and select specific attributes. For example using findAll with through

    1. User.findAll({
    2. include: [{
    3. model: Project,
    4. through: {
    5. attributes: ['createdAt', 'startedAt', 'finishedAt'],
    6. where: {completed: true}
    7. }
    8. }]