【问题标题】:How to disambiguate between multiple associations between the same models in Sequelize如何消除 Sequelize 中相同模型之间的多个关联之间的歧义
【发布时间】:2018-02-06 16:08:58
【问题描述】:

我有三个模型 — BookUserInstitution — 它们相互关联如下:

  • 书籍通过Book_Institution 连接表与机构相关联(多对多关系)

    Book.belongsToMany(models.Institution, { through: 'Book_Institution' })
    

    Institution.belongsToMany(models.Book, { through: 'Book_Institution' })
    
  • 用户可以通过两种方式与机构关联:作为读者或作者。这是通过两个连接表完成的:Author_InstitutionReader_Institution

    Institution.belongsToMany(models.User, { through: 'Author_Institution' })
    Institution.belongsToMany(models.User, { through: 'Reader_Institution' })
    

    User.belongsToMany(models.Institution, { through: 'Author_Institution' })
    User.belongsToMany(models.Institution, { through: 'Reader_Institution' })
    

    (为简洁起见,每次都省略foreignKey。)

我想查询Book 模型以查找属于某个作者的所有书籍。 Sequelize 提供了include 选项来轻松连接两个关联的表。我遇到的问题是使用include 如下所示默认为Reader_Institution 关联。如何指定应该使用哪个关联?

getBooks: (obj, args, context) => {
  const { user } = context

  return Book.findAll({
    attributes: ['id', 'path'],
    include: [{
      include: [{
        attributes: ['id'],
        model: User,
        where: { id: user }
      }],
      model: Institution,
      required: true // inner join
    }]
  })
}

提前感谢您的帮助。

【问题讨论】:

    标签: javascript join sequelize.js


    【解决方案1】:

    我使用as,它允许您通过该别名引用关系。

    Institution.belongsToMany(models.User, { 
        through: 'Author_Institution', // many-to-many relationship table name
        as: 'AuthorInstitution' // alias
    })
    

    以这种方式设置模型后,您可以使用as 指定查询时要包含的关系。

    getBooks: (obj, args, context) => {
      const { user } = context
    
      return Book.findAll({
        attributes: ['id', 'path'],
        include: [{
          include: [{
            attributes: ['id'],
            model: User,
            where: { id: user },
            as: 'AuthorInstitution'
          }],
          model: Institution,
          required: true // inner join
        }]
      })
    }
    

    此外,通过这种方法,您可以通过as 引用关系数据,因此您可以使用book.AuthorInstitution,它将是该对象的值。

    【讨论】:

    • 这不会导致一对多的关系而不是多对多的关系吗?
    • 不。我没有改变你的结构,你仍然会在每个对象上拥有belongsToMany,我只是将through 更改为as。我冒昧地猜测,如果您对此更满意,您可以直接添加 as,但 as 本质上只是为这种关系创建别名。
    • SequelizeAssociationError: belongsToMany must be given a through option, either a string or a model — 并且在关联定义中包含 as 不会使其在 include 中可用("User is associated to Institution using an alias. You've included an alias (test), but it does not match the alias defined in your association.",
    • 我找到了一些关于 through 选项的文档。它是关系表并且是必需的。我目前无法对此进行测试,但是您是否尝试将通道留在那里并将as 添加到您的关联中?确保将 as 添加到关联和包含中。
    • 谢谢!别名策略(使用as)似乎有效。我很困惑,因为User 的别名必须设置在Institution 上,所以我花了一些时间才正确实施您的答案。
    猜你喜欢
    • 2018-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-26
    • 1970-01-01
    • 2021-12-28
    相关资源
    最近更新 更多