如何在序列中实现多到多的关联

时间:2021-07-23 20:15:36

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});