node.js 如何在 sequelize 中实现多对多关联
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22958683/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to implement many to many association in sequelize
提问by Anuj
I have two tables: Books and Articles with a many-to-many relationship between them. Joining table is BookArticles.
我有两个表:Books 和 Articles,它们之间存在多对多关系。联接表是 BookArticles。
models/books.js
模型/books.js
module.exports = function(sequelize, DataTypes) {
return Food = sequelize.define("Book", {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false,
autoIncrement: true,
unique: true
}
});
}
models/articles.js
模型/文章.js
module.exports = function(sequelize, DataTypes) {
return Food = sequelize.define("Article", {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false,
autoIncrement: true,
unique: true
}
});
}
models/bookArticles.js
模型/bookArticles.js
module.exports = function(sequelize, DataTypes) {
return Food = sequelize.define("BookArticles", {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false,
autoIncrement: true,
unique: true
},
bookId: {
type: DataTypes.INTEGER,
references: 'Book',
referencesKey: 'id',
allowNull: false
},
ArticleId: {
type: DataTypes.INTEGER,
references: 'Article',
referencesKey: 'id',
allowNull: false
},
});
}
And models/index.js
和模型/index.js
m.BookArticles.belongsTo(m.Book);
m.Book.hasMany(m.Article, {through: m.BookArticles});
m.BookArticles.belongsTo(m.Article);
m.Article.hasMany(m.Books, {through: m.BookArticles});
but I could not get book articles
但我无法获得书籍文章
How can I get it ??
我怎么才能得到它 ??
回答by Calvintwr
Update 17 Feb 15:
1. The new v2, uses 2x .belongsToMany()for N:M.
Update 17 Feb 15: 1. 新的 v2,.belongsToMany()对 N:M使用 2x 。
There have been many problems in understanding all these associations.
在理解所有这些关联方面存在许多问题。
Generally I think we are confused as to what are the tables created, and what methods are gained by associations.
一般来说,我认为我们对创建的表是什么以及通过关联获得什么方法感到困惑。
The below text is something I wrote to standardise how I want my team to handle all these. As for the naming conventions, you may ignore it if you just let Sequelize default everything.
下面的文字是我写的东西,以标准化我希望我的团队如何处理所有这些。至于命名约定,如果你让 Sequelize 默认一切,你可能会忽略它。
However it is recommended to explicitly name your conventions for many reasons.
但是,出于多种原因,建议明确命名您的约定。
Brief:
简短的:
O:O, set up a Parent.hasOne(Child)AND Child.belongsTo(Parent).
O:O,设置一个Parent.hasOne(Child)AND Child.belongsTo(Parent)。
O:M, set up Parent.hasMany(Child)AND Child.belongsTo(Parent).
O:M,设置Parent.hasMany(Child)AND Child.belongsTo(Parent)。
N:M*, set up Parent.belongsToMany(Child, {through: 'Parent_Child', foreignKey: 'Parent_rowId'})and Child.belongsToMany(Parent, {through: 'Parent_Child', foreignKey: 'Child_rowId'}).
N:M*,设置Parent.belongsToMany(Child, {through: 'Parent_Child', foreignKey: 'Parent_rowId'})和Child.belongsToMany(Parent, {through: 'Parent_Child', foreignKey: 'Child_rowId'})。
Methods gained by hasOne(), hasMany() and belongsTo()/belongsToMany()
hasOne()、hasMany() 和belongsTo()/belongsToMany() 获得的方法
To understand why we do the above associations we start off by knowing what are the methods we gain for each model.
为了理解我们为什么要进行上述关联,我们首先要了解我们为每个模型获得的方法是什么。
hasOne():
有一个():
In setting a Parent.hasOne(Child), methods available to parentDAO instance:
在设置 a 时Parent.hasOne(Child),parentDAO 实例可用的方法:
parent.getChild,
parent.setChild,
parent.addChild,
parent.createChild,
parent.removeChild,
parent.hasChild
hasMany():
有很多():
In setting a Parent.hasMany(Child), methods available to parentDAO instance:
在设置 a 时Parent.hasMany(Child),parentDAO 实例可用的方法:
parent.getChildren,
parent.setChildren,
parent.addChild,
parent.createChild,
parent.removeChild,
parent.hasChild,
parent.hasChildren
belongsTo()/belongsToMany:
属于()/belongsToMany:
In setting a Child.belongsTo(Parent), methods available to childDAO instance:
在设置 a 时Child.belongsTo(Parent),childDAO 实例可用的方法:
child.getParent,
child.setParent,
child.createParent
//belongsToMany
child.getParents,
child.setParents,
child.createParents
The syntax for setting up relationships. And our conventions
建立关系的语法。还有我们的约定
For O:O, and O:M:
对于 O:O 和 O:M:
Parent.hasOne(Child, {foreignKey: 'Parent_childID'});
Child.belongsTo(Parent, {foreignKey: 'Parent_childID'});
Note that we explicitly defined our foreignKeys to be Parent_childID. This is because we want this PascalCase_camelCase for TableName_keyName convention.
请注意,我们明确地将外键定义为 Parent_childID。这是因为我们想要这个 PascalCase_camelCase 用于 TableName_keyName 约定。
Many to Many relationship
多对多关系
For a N:M relationship, do this:
对于 N:M 关系,请执行以下操作:
Parent.belongsToMany( Child, {
as: [Relationship],
through: [Parent_Child] //this can be string or a model,
foreignKey: 'Parent_rowId'
});
Child.belongsToMany(Parent, {
as: [Relationship2],
through: [Parent_Child],
foreignKey: 'Child_rowId'
});
*New in v2: Using "through" is now a must.
As a standard, using the "through" parameter, we explicitly define all the crosstable names for consistency and less gotchas.
*New in v2:现在必须使用“通过”。作为标准,使用“through”参数,我们明确定义所有交叉表名称以保持一致性和减少陷阱。
The above will create the Parent_Child, with RelationshipId and Relationship2ID.
以上将创建 Parent_Child,具有 RelationshipId 和 Relationship2ID。
Sequelize can create foreignKeys automagically, but I usually define my own.
Sequelize 可以自动创建外键,但我通常定义自己的。
Table and keys naming conventions
表和键命名约定
TableNames: PascalCase
表名:PascalCase
keys: camelCase
钥匙:驼峰式
foreignkeys: TableNameInPascalCase_foreignKeyInCamelCase
外键:TableNameInPascalCase_foreignKeyInCamelCase
Example: User_pictureId Meaning: This key of pictureId came from the User table.
示例:User_pictureId 含义:pictureId 的这个key 来自User 表。
回答by Sergey Karasev
delete BookArticles model and update relation to:
删除 BookArticles 模型并将关系更新为:
m.Book.hasMany(m.Article, {through: 'book_articles'});
m.Article.hasMany(m.Books, {through: 'book_articles'});
回答by Buhiire Keneth
This is how i solved the similar problem i had two models a user model
这就是我解决类似问题的方法我有两个模型一个用户模型
var user = sequelize.define('user', {
name: {
Sequelize.STRING(255)
},
email: {
type: Sequelize.STRING(255),
unique: true,
validate: {
isEmail: true
}
}
});
and a roles model
和榜样
var Role = sequelize.define('role', {
name: {
Sequelize.ENUM('ER', 'ALL', 'DL')
},
description: {
type: Sequelize.TEXT
}
});
Then i created the union model UserRole
然后我创建了联合模型 UserRole
var UserRole = sequelize.define('user_role', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: {
type: Sequelize.ENUM('Admin', 'Staff', 'Customer', 'Owner')
}
});
Note: you have to explicitly define the id for UserRole otherwise sequelize will use the two foreign keys in this case user_idand role_idas your primary keys.
注意:您必须明确定义 UserRole 的 id,否则 sequelize 在这种情况下将使用两个外键user_id并role_id作为您的主键。
Then i created the belongs to many relationship as follows
然后我创建了属于许多关系如下
User.belongsToMany(Role, { as: 'Roles', through: { model: UserRole, unique: false }, foreignKey: 'user_id' });
Role.belongsToMany(User, { as: 'Users', through: { model: UserRole, unique: false }, foreignKey: 'role_id' });
回答by Tilekbekov Yrysbek
M:Mrelation through table BookArticles:
M:M通过表的关系BookArticles:
m.Book.belongsToMany(m.Article, {through: m.BookArticles});
m.Article.belongsToMany(m.Books, {through: m.BookArticles});

