在.map(&:reload)期间会发生什么?

时间:2017-04-28 07:06:11

标签: ruby-on-rails arrays ruby activerecord

我们在我们的Rails应用程序中使用ActiveAdmin,其中包含Box模型。每当更新一个盒子阵列(认为具有任意,无关属性的Box模型)时(我在数组上使用.update_all而不是在阵列上的循环中使用.update),我们希望在每个框上创建一个属性更改日志(我们正在使用公共活动gem),这需要新近更新的Box数据。我遇到的一种策略是确保不将过时数据从内存数组传递到日志记录方法,这是在记录之前调用数组上的.map(&:reload)

虽然这确实解决了这个问题,但我很好奇这是否会在数据库上进行N次提取查询,否则更好的选择似乎是执行Box.find(id: <array_of_ids>)然后在每个对象上调用logging方法。哪个更值得建议避免可避免的数据库命中?

1 个答案:

答案 0 :(得分:0)

collection.map(&:reload)只是以下代码的快捷方式:

collection.map do |item|
  item.reload
end

甚至还有(&amp;:方法)符号的名称:&#34; Ruby Pretzel Syntax&#34;。所以在这种情况下它会做一个n + 1。

更好的方法是直接在reload上致电ActiveRecord::Relation

collection = MyModel.where(...)

# do some stuff that would change a part of the resulting query..

collection.reload

这样,查询将再次执行,并将新结果分配给您的collection变量。

或者如果您的集合是数组,请自行构建查询。 e.g:

MyModel.where(id: collection.map(&:id))