使用Sequelize更新关联模型中的属性

是否可以一次更新父模型和相关模型的属性? 我无法正常工作,一直没能find完整的例子。 我不确定它是否是我的代码错误,或者如果它不打算按我期望的方式工作。 我尝试将onUpdate:'cascade'添加到我的hasMany定义中,但是这似乎没有做任何事情。

楷模:

module.exports = function( sequelize, DataTypes ) { var Filter = sequelize.define( 'Filter', { id : { type : DataTypes.INTEGER, autoIncrement : true, primaryKey : true }, userId : DataTypes.INTEGER, filterRetweets : DataTypes.BOOLEAN, filterContent : DataTypes.BOOLEAN }, { tableName : 'filter', timestamps : false } ); var FilteredContent = sequelize.define( 'FilteredContent', { id : { type : DataTypes.INTEGER, autoIncrement : true, primaryKey : true }, filterId : { type : DataTypes.INTEGER, references : "Filter", referenceKey : "id" }, content : DataTypes.STRING }, { tableName : "filteredContent", timestamps : false } ); Filter.hasMany( FilteredContent, { onUpdate : 'cascade', as : 'filteredContent', foreignKey : 'filterId' } ); sequelize.sync(); return { "Filter" : Filter, "FilteredContent" : FilteredContent }; } 

检索filter并尝试更新关联的FilteredContent对象上的属性:

 Filter.find({ where: { id: 3 }, include: [ { model : FilteredContent, as : 'filteredContent' } ] }).success ( function( filter ) { var filteredContent = FilteredContent.build( { filterId : filter.id, id : 2, content : 'crap' }); filter.save(); }); 

这将导致只更新Filter对象中的属性。 我如何获得它也更新FilteredContent中的属性?

另外,定义我的模型后,sequelize.sync()是必要的吗? 我不清楚它应该做什么。 我能够检索我的对象没有它的关联。 我绝望地将它添加到我的代码中以使更新正常工作,但我不确定是否真的有必要。

谢谢

对你的问题:

当你急切地加载FilteredContent(使用include)时,模型实例已经build好了,所以没有理由调用build 。 沿着这个线应该做你想要的东西:

 Filter.find({ where: { id: 3 }, include: [ { model : FilteredContent, as : 'filteredContent' } ] }).then ( function( filter ) { return filter.filteredContent[0].updateAttributes({ content: 'crap' }) }).then(function () { // DONE! :) }); 

关于您整个发布的代码的几个指针:

  • sequelize.sync为您的模型创build数据库表,如果它们不存在的话。 如果你的表已经存在,你不需要做什么
  • sequelize.sync是一个asynchronous操作,因此不build议在不附加callback的情况下执行sequelize.sync。 此外,它看起来像是在模型定义中进行同步 – 您应该只做一次,最好是在您定义模型的地方。
  • 它看起来像你在一个文件中定义几个模型 – 你应该只在每个文件中定义一个模型。 可以通过在FilterContent文件中执行sequelize.import([filter模型的path]),或者在将模型导入到应用程序的位置执行所有关联来设置关联。

编辑回答你的评论:

你不能做一个单独的函数调用来更新filter和过滤内容,但是你也不需要依次执行更新。 您可以发出所有更新命令,而无需等待它们完成。

 Filter.find({ where: { id: 3 }, include: [ { model : FilteredContent, as : 'filteredContent' } ] }).then ( function( filter ) { return Promise.all([ filter.updateAttributes({}), filter.filteredContent.map(fc => fc.updateAttributes({})) ]); }).spread(function (filter, filteredContents) { }) 

通过这种方式,所有查询都将并行运行,并且当所有查询都完成时,您的函数将被调用。 请注意,我已经在这里使用spread将从Promise.all返回的数组Promise.all为单独的参数。