I have two tables: Books and Articles with a many-to-many relationship between them. Joining table is BookArticles.
我有两个表:书籍和文章,它们之间有多对多的关系。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
模型/ articles.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 ??
我怎样才能得到它?
4 个解决方案
#1
13
delete BookArticles model and update relation to:
删除BookArticles模型和更新关系到:
m.Book.hasMany(m.Article, {through: 'book_articles'});
m.Article.hasMany(m.Books, {through: 'book_articles'});
#2
146
Update 17 Feb 15
: 1. The new v2, uses 2x .belongsToMany()
for N:M.
2月15日更新:1。新的v2,对N:M使用2x . belongstomany()。
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:M, set up 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 *,设置父。所属关系(Child,{通过:Parent_Child', foreignKey: Parent_rowId'})和Child。归属感(父母,{通过:'Parent_Child', foreignKey: 'Child_rowId'})。
Methods gained by hasOne(), hasMany() and 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 parent
DAO instance:
在设置parent . hasone (Child)时,父DAO实例可用的方法有:
parent.getChild,
parent.setChild,
parent.addChild,
parent.createChild,
parent.removeChild,
parent.hasChild
hasMany():
In setting a Parent.hasMany(Child)
, methods available to parent
DAO instance:
在设置Parent.hasMany(子)时,父DAO实例可用的方法:
parent.getChildren,
parent.setChildren,
parent.addChild,
parent.createChild,
parent.removeChild,
parent.hasChild,
parent.hasChildren
belongsTo()/belongsToMany:
In setting a Child.belongsTo(Parent)
, methods available to child
DAO instance:
在设置child . belongsto(父)时,子DAO实例可用的方法是:
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:
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.
*新版本v2:现在必须使用“通过”。作为一种标准,我们使用“通过”参数显式地定义所有的可交叉的名称,以保证一致性和更少的陷阱。
The above will create the Parent_Child, with RelationshipId and Relationship2ID.
上面将创建具有关系和关系2 id的Parent_Child。
Sequelize can create foreignKeys automagically, but I usually define my own.
Sequelize可以自动创建外国键,但我通常定义我自己的。
Table and keys naming conventions
TableNames: PascalCase
表名:PascalCase
keys: camelCase
键:camelCase
foreignkeys: TableNameInPascalCase_foreignKeyInCamelCase
foreignkeys:TableNameInPascalCase_foreignKeyInCamelCase
Example: User_pictureId Meaning: This key of pictureId came from the User table.
示例:User_pictureId含义:图id的这个键来自于用户表。
#3
5
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
然后我创建了union模型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_id
and role_id
as 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' });
#4
2
M:M
relation through table BookArticles
:
M:通过餐桌书的关系:
m.Book.belongsToMany(m.Article, {through: m.BookArticles});
m.Article.belongsToMany(m.Books, {through: m.BookArticles});
#1
13
delete BookArticles model and update relation to:
删除BookArticles模型和更新关系到:
m.Book.hasMany(m.Article, {through: 'book_articles'});
m.Article.hasMany(m.Books, {through: 'book_articles'});
#2
146
Update 17 Feb 15
: 1. The new v2, uses 2x .belongsToMany()
for N:M.
2月15日更新:1。新的v2,对N:M使用2x . belongstomany()。
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:M, set up 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 *,设置父。所属关系(Child,{通过:Parent_Child', foreignKey: Parent_rowId'})和Child。归属感(父母,{通过:'Parent_Child', foreignKey: 'Child_rowId'})。
Methods gained by hasOne(), hasMany() and 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 parent
DAO instance:
在设置parent . hasone (Child)时,父DAO实例可用的方法有:
parent.getChild,
parent.setChild,
parent.addChild,
parent.createChild,
parent.removeChild,
parent.hasChild
hasMany():
In setting a Parent.hasMany(Child)
, methods available to parent
DAO instance:
在设置Parent.hasMany(子)时,父DAO实例可用的方法:
parent.getChildren,
parent.setChildren,
parent.addChild,
parent.createChild,
parent.removeChild,
parent.hasChild,
parent.hasChildren
belongsTo()/belongsToMany:
In setting a Child.belongsTo(Parent)
, methods available to child
DAO instance:
在设置child . belongsto(父)时,子DAO实例可用的方法是:
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:
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.
*新版本v2:现在必须使用“通过”。作为一种标准,我们使用“通过”参数显式地定义所有的可交叉的名称,以保证一致性和更少的陷阱。
The above will create the Parent_Child, with RelationshipId and Relationship2ID.
上面将创建具有关系和关系2 id的Parent_Child。
Sequelize can create foreignKeys automagically, but I usually define my own.
Sequelize可以自动创建外国键,但我通常定义我自己的。
Table and keys naming conventions
TableNames: PascalCase
表名:PascalCase
keys: camelCase
键:camelCase
foreignkeys: TableNameInPascalCase_foreignKeyInCamelCase
foreignkeys:TableNameInPascalCase_foreignKeyInCamelCase
Example: User_pictureId Meaning: This key of pictureId came from the User table.
示例:User_pictureId含义:图id的这个键来自于用户表。
#3
5
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
然后我创建了union模型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_id
and role_id
as 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' });
#4
2
M:M
relation through table BookArticles
:
M:通过餐桌书的关系:
m.Book.belongsToMany(m.Article, {through: m.BookArticles});
m.Article.belongsToMany(m.Books, {through: m.BookArticles});