更新模型时如何更新hasMany关联?

时间:2018-12-04 23:48:36

标签: javascript node.js sequelize.js

是否有一种方法可以在一次调用中更新对象(组织)及其关联(tasg)?就我而言,我有组织->标签。一个组织可以有很多标签。

我无法通过一次简单的电话就知道如何更新标签和组织

function updateOrganization(db, stats) {
  return function (req, res) {
    let myOrg

    db.organization.findOne({
      where: {
        id: req.params.id
      },
      include: ['tags']
    })
      .then(org => {
        myOrg = org
        let promises = []

        if (req.body.tags) {
          req.body.tags.forEach(tag => {
            promises.push(org.createTag({ name: tag }))
          })
        }

        return Promise.all(promises)
      })
      .then(tags => {
        console.log('tags = ', tags)

        return myOrg.setTags(tags) <-- DOES NOT SEEM TO BE WORKING
      })
     .then(updatedOrg => {
       console.log('updatedOrg.get() = ', updatedOrg.get()) <-- DOES NOT CONTAIN NEW TAGS
       console.log('myOrg final = ', myOrg.get()) <-- DOES NOT CONTAIN NEW TAGS
       return res.status(HttpStatus.OK).send(myOrg)
      })
      .catch(err => {
        req.log.error(err)
        return handleErr(res, HttpStatus.INTERNAL_SERVER_ERROR, err.message)
      })
  }
}

注意:看起来promises.push(org.createTag({ name: tag }))行实际上是在创建标签,而return myOrg.setTags(tags)行不是必需的。当我使用findOne查询获取此记录时,所有标记实际上都存在。那么,为什么在updatedOrg输出的日志语句中不显示它们?

2 个答案:

答案 0 :(得分:1)

您可以简单地使用以下内容:

function updateOrganization(db, stats) {
  return async (req, res) => {
    try {
      // Get the organization + associations
      const org = await Organization.find({
        where: { id: req.params.id },
        include: ['tags'],
        limit: 1, // added this because in the 4.42.0 version '.findOne()' is deprecated
      });

      // Check if we have any tags specified in the body
      if(req.body.tags) {
        await Promise.all(req.body.tags.map(tag => org.createTag({ name: tag })));
      }

      return res.status(HttpStatus.OK).send(org.reload()); // use '.reload()' to refresh associated data
    } catch(err) {
      req.log.error(err);
      return handleErr(res, HttpStatus.INTERNAL_SERVER_ERROR, err.message);
    }
  }
}

您可以详细了解.reload() here

我还建议您以后使用Sequelize Transactions,这将非常容易控制您的应用程序流。

答案 1 :(得分:0)

确定要建立“ hasMany”关系吗?通常,标签是共享的,并且组织将具有“ belongsToMany”关系。请发布您的模型和架​​构,并在可能的情况下发布一个有效的示例(使用您的架构连接到数据库)或一个示例的链接。

无论如何,我相信createTag仅在标记不存在时才起作用。如果标签存在,则需要setTagsaddTags,传入标签对象或其主键ID。