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

Ruby on rails 在Rails中的一个ActiveRecord事务中更新多个记录,ruby-on-rails,ruby,postgresql,activerecord,transactions,Ruby On Rails,Ruby,Postgresql,Activerecord,Transactions,如何使用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似乎发出自己的事

如何使用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
似乎发出自己的事务,而不是将更新批处理到周围的事务中。我希望所有的更新都能在一个大交易中完成


我怎样才能做到这一点呢?

我不确定,但您可能将多个事务与多个查询混淆了

您发布的代码将创建一个事务(例如,如果发生异常,则所有更新都将回滚),但每个
保存
都将导致单独的更新查询


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

假设您知道要将ID 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
来执行类似于上述的块,但插入了正确的值字符串。

我认为您只需要将方法“save”更改为“save!”。 如果任何更新失败,方法将保存!生成一个异常。当事务块内发生异常时,事务将反转整个操作(回滚)


我必须一次对1000条左右的记录运行更新,所以我不想运行1000个单独的更新查询,因为这要慢得多。你能一次全部执行吗?如果更新真的要将
得分设置为2个随机数的总和(你不仅仅是用这个例子来简化问题)然后,您可以使用
update\u all
,但使用postgres
random
函数设置值,而不是使用固定值。可能activerecord导入对您有效。这将生成多个SQL请求。
MyModel.transaction do
    things_to_update.each do |thing|
    thing.score = rand(100) + rand(100)
    thing.save!
end