如何在sequelize中实现多对多关联

新手上路,请多包涵

我有两个表: Books 和 Articles 之间存在多对多关系。连接表是 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
    },
  });
}

和模型/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});

但我无法获得书籍文章

我怎么才能得到它 ??

原文由 Anuj 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 512
2 个回答

Sequelize 协会备忘单

为 Sequelize v2/3/4/5 更新

一般来说,我认为问题在于我们对创建什么表以及关联获得什么方法感到困惑。

注意:定义 foreignKey 或交叉表名称是可选的。 Sequelize 自动创建它,但定义它允许编码人员读取模型并找出外键/交叉表名称是什么,而不是猜测或需要访问数据库。

TLDR;

O:O

 // foreign key has to be defined on both sides.
Parent.hasOne(Child, {foreignKey: 'Parent_parentId'})
// "Parent_parentId" column will exist in the "belongsTo" table.
Child.belongsTo(Parent, {foreignKey: 'Parent_parentId'})

O:M

 Parent.hasMany(Child, {foreignKey: 'Parent_parentId'})
Child.belongsTo(Parent, {foreignKey: 'Parent_parentId'})

N:M

 Parent.belongsToMany(
    Child,
    {
        // this can be string (model name) or a Sequelize Model Object Class
        // through is compulsory since v2
        through: 'Parent_Child',

        // GOTCHA
        // note that this is the Parent's Id, not Child.
        foreignKey: 'Parent_parentId'
    }
)

/*
The above reads:
"Parents" belongs to many "Children", and is recorded in the "Parent_child" table, using "Parents"'s ID.
*/

Child.belongsToMany(
    Parent,
    {
        through: 'Parent_Child',

        // GOTCHA
        // note that this is the Child's Id, not Parent.
        foreignKey: 'Child_childId'
    }
)

为什么冗长的“Parent_parentId”而不仅仅是“parentId”?这是为了清楚地表明它是属于“父”的外键。在大多数情况下,只使用更简洁的“parentId”是可以的。*

关联为您提供 2 个功能:(1) 急切加载和 (2) DAO 方法:

1. 包括(急切加载)

 DB.Parent.findOne({
    where: { id: 1 },
    include: [ DB.Child ]
}).then(parent => {

    // you should get `parent.Child` as an array of children.

})

2. hasOne()、hasMany()和belongsTo()/belongsToMany()获得的方法

关联提供数据访问对象 (DAO) 方法:

有一个():

在设置 Parent.hasOne(Child) 时,可用于 parent DAO 实例的方法:

 DB.Parent.findOne({ where: { id: 1 } }).then(parent => {

    // `parent` is the DAO
    // you can use any of the methods below:
    parent.getChild
    parent.setChild
    parent.addChild
    parent.createChild
    parent.removeChild
    parent.hasChild

})

有很多():

在设置 Parent.hasMany(Child) 时,可用于 parent DAO 实例的方法:

 parent.getChildren,
parent.setChildren,
parent.addChild,
parent.addChildren,
parent.createChild,
parent.removeChild,
parent.hasChild,
parent.hasChildren,

属于()/属于多:

在设置 Child.belongsTo(Parent) 时,可用于 child DAO 实例的方法:

 child.getParent,
child.setParent,
child.createParent,

//belongsToMany
child.getParents,
child.setParents,
child.createParents,

你也可以有多个关系

亲生父母/孩子

// a parent can have many children
Parent.belongsToMany(Child, {
    as: 'Natural',
    through: 'Parent_Child',
    foreignKey: 'Parent_parentId'
})
// a child must at least have 2 parents (natural mother and father)
Child.belongsToMany(Parent, {
    as: 'Natural',
    through: 'Parent_Child',
    foreignKey: 'Child_childId'
})

寄养父母/儿童

Parent.belongsToMany(Child, {
    as: 'Foster',
    through: 'Parent_Child',
    foreignKey: 'Parent_parentId'
})

Child.belongsToMany(Parent, {
    as: 'Foster',
    through: 'Parent_Child',
    foreignKey: 'Child_childId'
});

以上将创建 Parent_Child 交叉表,带有 NaturalIdFosterId

原文由 Calvintwr 发布,翻译遵循 CC BY-SA 4.0 许可协议

删除 BookArticles 模型并更新关系到:

 m.Book.hasMany(m.Article, {through: 'book_articles'});
m.Article.hasMany(m.Books, {through: 'book_articles'});

原文由 Sergey Karasev 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题