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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 17:08:05  来源:igfitidea点击:

How to implement many to many association in sequelize

node.jsexpresssequelize.js

提问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_idrole_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});