在Rails中的一个ActiveRecord事务中更新多个记录

如何使用Rails中的事务块一次更新/保存模型的多个实例?

我想更新数百条记录的值; 每条记录的值都不同。 这不是一个属性的批量更新情况。 Model.update_all(attr:value)在这里不合适。

MyModel.transaction do things_to_update.each do |thing| thing.score = rand(100) + rand(100) thing.save end end 

save似乎发布了它自己的事务,而不是将更新批处理到周围的事务中。 我希望所有更新都进入一次重大交易。

我怎么能做到这一点?

假设你知道你想用ids 1,2和3来设置得分,2分,8分和64分(而不是随机数),你可以:

 UPDATE things AS t SET score = c.score FROM (values (1, 2), (2, 30), (4, 50) ) as c(id, score) where c.id = t.id; 

所以使用Rails,你可以使用ActiveRecord::Base.connection#execute来执行类似于上面的块,但是插入了正确的值字符串。

我不确定,但是你可能会混淆多个查询的 多个事务

您发布的代码将创建单个事务(例如,如果发生exception,则所有更新都将回滚),但每次save都会导致单独的更新查询。

如果可以使用SQL而不是Ruby代码执行更新,那么这可能是最好的方法。

我认为你需要改变方法“保存”到“保存!”。 如果任何更新失败,方法保存! 生成exception。 当事务块中发生exception时,事务会反转整个操作(回滚)

 MyModel.transaction do things_to_update.each do |thing| thing.score = rand(100) + rand(100) thing.save! end