Sequelize返回查询中的联接表

Kev*_*gts 6 mysql node.js sequelize.js

我的MSQL表中有这两个模型之间的多对多关系:

  • 场地-代表可以有多个所有者(雇员)的场地
  • 员工-代表可以是首席执行官,销售员工或任何其他形式的员工。

我正在使用建立这样的关系:

关系员工>地点

 Employee.associate = function (models) { 
   models.Employee.belongsToMany(models.Venue, { through: 'EmployeeVenues' })
 }
Run Code Online (Sandbox Code Playgroud)

关系地点>员工

 Venue.associate = function (models) {
    models.Venue.belongsToMany(models.Employee, { through: 'EmployeeVenues' })
 }
Run Code Online (Sandbox Code Playgroud)

续集文档

根据Sequelize文档,它将创建一个名为EmployeeVenues的新模型,该模型具有等效的外键employee_id和场所_id。需要通过定义。Sequelize以前会尝试自动生成名称,但这并不总是导致最合理的设置。这会将方法getVenues,setVenues,addVenue,addUsers添加到Employee中。


并且这是正确的,当我启动我的Sequelize时,它将创建一个名为EmpoyeeVenues的新表,并使用正确的外键作为复合键。但是,当我查询getVenues时,它不会返回预期的输出。相反,它也返回关联的表值,这是我不想要的。


查询以获取属于ID等于1的员工的所有场所


router.get('/api/v1/users/:employee_id/venues', (request, response) => {
  var employeeId = request.params.employee_id;

  models.Employee.findOne({
    where: {id: employeeId}
  }).then((employee) => {

    if(!employee) { return response.status(400).send("Employee doesnt have a venue registered yet.")}
    var venues = employee.getVenues().then((venues) => {
    response.status(200).send(venues);
  })
})
});
Run Code Online (Sandbox Code Playgroud)

回应结果


[
    {
        "id": 1,
        "capacity": "11",
        "venue_name": "Club Fix",
        "venue_description": "Club in Tilburg",
        "EmployeeVenues": {
            "employee_id": 1,
            "venue_id": 1
        }
    },
    {
        "id": 2,
        "capacity": "400",
        "venue_name": "Club Vie",
        "venue_description": "Club in Rotterdam",
        "EmployeeVenues": {
            "employee_id": 1,
            "venue_id": 2
        }
    }
]
Run Code Online (Sandbox Code Playgroud)

为什么Sequelize在此查询中包含EmployeeVenues?并且如何防止EmployeeVenues包含在响应中?


更新资料

根据2014年制作的Sequelize github页面上的一个问题,有一个可行的解决方案

https://github.com/sequelize/sequelize/issues/2143

    User.find({
    where: {id: userId}, attributes: userFields,
    include: [
      {model: db.Role, attributes: roleFields, through: {attributes: []}}
    ]
});
Run Code Online (Sandbox Code Playgroud)

但是,它与最新版本的Sequelize文档中的文档版本不匹配,至少应该如此。


User.findAll({
  include: [{
    model: Project,
    through: {
      attributes: ['createdAt', 'startedAt', 'finishedAt'],
      where: {completed: true}
    }
  }]
});
Run Code Online (Sandbox Code Playgroud)

甚至简单地在参考文档中说明:


user.getPictures() // gets you all pictures
Run Code Online (Sandbox Code Playgroud)

Kev*_*gts 5

更新

根据 2014 年创建的 Sequelize github 页面上的一个问题,有一个有效的解决方案

https://github.com/sequelize/sequelize/issues/2143

    User.find({
    where: {id: userId}, attributes: userFields,
    include: [
      {model: db.Role, attributes: roleFields, through: {attributes: []}}
    ]
});
Run Code Online (Sandbox Code Playgroud)

但它与最新的 Sequelize 文档中记录的版本不匹配,至少应该是这样。


User.findAll({
  include: [{
    model: Project,
    through: {
      attributes: ['createdAt', 'startedAt', 'finishedAt'],
      where: {completed: true}
    }
  }]
});
Run Code Online (Sandbox Code Playgroud)

或者甚至在参考文档中简单说明


user.getPictures() // gets you all pictures
Run Code Online (Sandbox Code Playgroud)


Abh*_*hah 5

我认为给出的答案遗漏了一件需要的重要事情 - 在哪里保存所包含模型所需的属性,在这里 - Project。github上的问题已经有了最终答案,但仍然不是我期待的完整答案。

\n\n

我们需要在模型级别重新指定属性,然后将连接表属性设置为none

\n\n
User.findAll({\n  include: [{\n    model: Project,\n\n    through: \'JoinTableAliasName\' /// only if exist/needed\n    as: \'modelAssociationAlias\' // only if exist/needed\n\n    // attributes needed from Project table\n    attributes: [\'createdAt\', \'startedAt\', \'finishedAt\'],\n\n    through: { // through again doesn\'t create any issue\n      attributes: [], // this helps removing the join table in returned data\n      where: {completed: true}\n    }\n  }]\n});\n
Run Code Online (Sandbox Code Playgroud)\n