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



是否可以一次更新父模型和相关模型的属性?我有麻烦得到它的工作,并没有能够找到任何完整的例子。我不确定是我的代码出了问题,还是它不打算按我期望的方式工作。我试着添加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中的属性?

另外,在定义模型后是否需要sequize .sync() ?我不清楚它到底应该做什么。我可以检索没有关联的对象。我绝望地将它添加到我的代码中以使更新工作,但我不确定它是否实际上是必要的。

谢谢

你的问题:

当您急切加载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! :)
});

关于你作为一个整体发布的代码的几个指针:

  • sequelize。Sync为您的模型创建数据库表,如果它们还不存在的话。如果您的表已经存在
  • ,则不需要执行此操作。
  • sequelize。同步是一个异步操作,所以执行序列化。不附带回调的同步是不可取的。此外,它看起来像你在模型定义中做同步-你应该只做一次,最好在你定义模型的地方。
  • 看起来你在一个文件中定义了几个模型-你应该在每个文件中只定义一个。关联可以通过sequelize来建立。在你的FilterContent文件中导入([路径到过滤器模型),或者在你导入模型到应用程序的地方做所有的关联。

编辑回复您的评论:

你不能做一个函数调用来同时更新filter和filteredcontent,但是你也不必按顺序进行更新。您可以发出所有的更新命令,而不必等待它们完成。

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返回的数组转换为单独的参数。

对于@hatchifyjs/sequelize-create-with-associations,它很简单:

await Filter.update({
  filteredContent: [
    { content: "x" },
    { content: "y" },
  ]
}, { where: { id: 3 } });

最新更新