Reputation: 2096
In a Node + MySQL project I got 4 Tables:
Users
describes a registered user,InvitedUsers
a proto-user, contains some informations of a non registered user,Projects
describes a project,ProjectMembers
the N:M associations of Projects
and Users
Now I got the association of the N:M like this:
Users.belongsToMany(Projects, { through: ProjectMembers });
Projects.belongsToMany(Users, { through: ProjectMembers });
I need to use the same ProjectMembers
table as N:M for InvitedUsers
and Projects
Is this possible? I suppose that it's not since the foreign key constrains on the N:M table cannot choose on which table (Users
or InvitedUsers
) has to be applied
I've tried adding (omitting the options):
InvitedUsers.belongsToMany(Projects, { through: ProjectMembers });
Projects.belongsToMany(InvitedUsers, { through: ProjectMembers });
And no error is displayed during the associations definition but when i try to add an entry in the ProjectMembers
table coping a InvitedUsers
's id as FK, I got a foreign key constrain error.
So my question is if I can use a N:M table for different N:M relations.
Upvotes: 4
Views: 664
Reputation: 609
Did you try creating different alias using as
option in belongsToMany
So, your associations might look like this -
//User-projects via ProjectMembers
Users.belongsToMany(Projects, { through: ProjectMembers, as: 'ProjectMembers' });
Projects.belongsToMany(Users, { through: ProjectMembers, as: 'ProjectMembers' });
//InvitedUsers-Projects via ProjectMembers
InvitedUsers.belongsToMany(Projects, { through: ProjectMembers, as: 'ProjectInvitedMembers' });
Projects.belongsToMany(InvitedUsers, { through: ProjectMembers, as: 'ProjectInvitedMembers' });
Upvotes: 0
Reputation: 7282
yes, this can be done as long as you specify which foreignKey
the association should use for joining the tables. You can specify two different keys, one for user
and one for the InvitedUser
and Sequelize will pick the right key.
User.belongsToMany(Project, { through: ProjectMembers, foreignKey: 'user_id' });
Project.belongsToMany(User, { through: ProjectMembers, foreignKey: 'project_id' });
Invited.belongsToMany(Project, { through: ProjectMembers, foreignKey: 'invited_id' });
Project.belongsToMany(Invited, { through: ProjectMembers, foreignKey: 'project_id' });
This is how the schema of project_members
would look like
Below is the full working code
const User = sequelize.define('user', {
username: Sequelize.STRING,
});
const Invited = sequelize.define('invited', {
username: Sequelize.STRING,
});
const Project = sequelize.define('project', {
name: Sequelize.STRING,
});
const ProjectMembers = sequelize.define('project_members', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
user_id: {
type: Sequelize.INTEGER,
},
project_id: Sequelize.INTEGER,
invited_id: Sequelize.INTEGER,
});
User.belongsToMany(Project, { through: ProjectMembers, foreignKey: 'user_id' });
Project.belongsToMany(User, { through: ProjectMembers, foreignKey: 'project_id' });
Invited.belongsToMany(Project, { through: ProjectMembers, foreignKey: 'invited_id' });
Project.belongsToMany(Invited, { through: ProjectMembers, foreignKey: 'project_id' });
sequelize.sync({ force: true })
.then(() => {
User.create({
username: 'UserOne',
projects: {
projectName: 'projectOne'
}
}, { include: [Project] }).then((result) => {
Invited.create({
username: 'InvitedOne',
projects: {
projectName: 'projectTwo'
}
}, { include: [Project] }).then((result2) => {
console.log(result2);
})
})
})
Upvotes: 1
Reputation: 142218
Speaking from MySQL's perspective...
A many:many database table is essentially 2 columns (project_id
, person_id
) with two indexes ((project_id, person_id)
and (person_id, project_id)
). If is reasonable to add a 3rd column to qualify the type of relationship between the ("member" versus "invited user").
More discussion of the table: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table
Upvotes: 4