是否可以一次性更新父模型和关联模型的属性?我无法让它工作,也无法找到任何完整的例子。我不确定我的代码是否有问题,或者它是否打算以我期望的方式工作。我尝试将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
};
}
检索过滤器并尝试更新关联的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()?我不清楚应该做什么。没有它我可以用关联检索我的对象。我绝望地将它添加到我的代码中以使更新正常工作,但我不确定它是否真的有必要。
由于
答案 0 :(得分:25)
问题:
当您急切地加载FilteredContent(使用include)时,已经构建了一个模型实例,因此没有理由调用build
。根据这一点,你应该做你想做的事情:
Filter.find({
where: { id: 3 },
include: [ { model : FilteredContent, as : 'filteredContent' } ]
}).then ( function( filter ) {
return filter.filteredContent[0].updateAttributes({
content: 'crap'
})
}).then(function () {
// DONE! :)
});
关于您发布的代码的几点建议:
编辑以回答您的评论:
您无法执行将更新过滤器和过滤内容的单个函数调用,但您也不必按顺序执行更新。您可以发出所有更新命令,而无需等待它们完成。
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) {
})
通过这种方式,所有查询都将并行运行,并且当所有查询都已完成时,将调用then函数。请注意,我在这里使用spread
将从Promise.all
返回的数组转换为单独的参数。