如何实现多对多关联的续集
我有两个表格:书籍和文章之间有多对多的关系。 参加表是BookArticles。
车型/ books.js
module.exports = function(sequelize, DataTypes) { return Food = sequelize.define("Book", { id: { type: DataTypes.INTEGER, primaryKey: true, allowNull: false, autoIncrement: true, unique: true } }); }
车型/ articles.js
module.exports = function(sequelize, DataTypes) { return Food = sequelize.define("Article", { id: { type: DataTypes.INTEGER, primaryKey: true, allowNull: false, autoIncrement: true, unique: true } }); }
车型/ 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 }, }); }
和models / 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});
但我无法获得书籍文章
我怎么才能得到它 ??
删除BookArticles模型并更新关系:
m.Book.hasMany(m.Article, {through: 'book_articles'}); m.Article.hasMany(m.Books, {through: 'book_articles'});
Update 17 Feb 15
:1.新的v2,使用.belongsToMany()
为N:M。
了解所有这些协会已经有很多问题。
一般来说,我们认为我们对创build的表格感到困惑,联想获得了什么方法。
下面的文字是我写的标准化我希望我的团队如何处理所有这些。 至于命名约定,如果只让Sequelize默认所有内容,则可以忽略它。
但是,由于多种原因,build议明确指定您的约定。
简要:
O:O,build立一个Parent.hasOne(Child)
和Child.belongsTo(Parent)
。
O:M,设置Parent.hasMany(Child)
和Child.belongsTo(Parent)
。
N:M *,设置Parent.belongsToMany(Child, {through: 'Parent_Child', foreignKey: 'Parent_rowId'})
和Child.belongsToMany(Parent, {through: 'Parent_Child', foreignKey: 'Child_rowId'})
。
hasOne(),hasMany()和belongsTo()/ belongsToMany()
为了理解为什么我们做了上述的关联,我们首先知道我们为每个模型获得了什么方法。
hasOne():
在设置Parent.hasOne(Child)
方法中, parent
DAO实例可用:
parent.getChild, parent.setChild, parent.addChild, parent.createChild, parent.removeChild, parent.hasChild
有很多():
在设置Parent.hasMany(Child)
方法中, parent
DAO实例可用:
parent.getChildren, parent.setChildren, parent.addChild, parent.createChild, parent.removeChild, parent.hasChild, parent.hasChildren
属于关联()/ belongsToMany:
在设置Child.belongsTo(Parent)
, child
DAO实例可用的方法:
child.getParent, child.setParent, child.createParent //belongsToMany child.getParents, child.setParents, child.createParents
设置关系的语法。 和我们的约定
对于O:O和O:M:
Parent.hasOne(Child, {foreignKey: 'Parent_childID'}); Child.belongsTo(Parent, {foreignKey: 'Parent_childID'});
请注意,我们明确地将foreignKeys定义为Parent_childID。 这是因为我们想为TableName_keyName约定使用这个PascalCase_camelCase。
多对多的关系
对于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
:使用“直通”现在是必须的。 作为一个标准,使用“through”参数,我们明确地定义了所有可交叉名称,以获得一致性和更less的陷阱。
以上将创buildParent_Child与RelationshipId和Relationship2ID。
Sequelize可以自动创buildforeignKeys,但我通常定义自己的。
表和键命名约定
TableNames:PascalCase
键:camelCase
外键:TableNameInPascalCase_foreignKeyInCamelCase
示例:User_pictureId含义:pictureId的这个键来自User表。
这是我如何解决了我有两个模型的用户模型类似的问题
var user = sequelize.define('user', { name: { Sequelize.STRING(255) }, email: { type: Sequelize.STRING(255), unique: true, validate: { isEmail: true } } });
和一个angular色模型
var Role = sequelize.define('role', { name: { Sequelize.ENUM('ER', 'ALL', 'DL') }, description: { type: Sequelize.TEXT } });
然后我创build了联合模型UserRole
var UserRole = sequelize.define('user_role', { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, name: { type: Sequelize.ENUM('Admin', 'Staff', 'Customer', 'Owner') } });
注意:你必须明确地为UserRole定义id,否则sequelize会在这种情况下使用两个外键, user_id
和role_id
作为你的主键。
然后我创build了属于许多关系如下
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' });
M:M
关系通过表BookArticles
:
m.Book.belongsToMany(m.Article, {through: m.BookArticles}); m.Article.belongsToMany(m.Books, {through: m.BookArticles});