现在在Rails 4中不推荐使用ActiveRecord :: Relation#all,你应该如何迭代所有记录?
过去就像:
Foo.all.each do |foo|
# whatever
end
我现在可以这样近似,但感觉很脏:
Foo.where(true).each do |foo|
# whatever
end
有更好的方法吗?
答案 0 :(得分:62)
根据Rails Guide on Active Record Query Interface,迭代所有记录的正确方法是使用find_each
。
使用Foo.all.each
会将整个表加载到内存中,实例化所有行;然后遍历实例。 find_each
分批执行此操作,这在内存使用方面更有效。
从指南中:
find_each
方法检索一批记录,然后将每个记录单独作为模型生成到块中。在以下示例中,find_each
将检索1000条记录(find_each
和find_in_batches
的当前默认值),然后将每条记录单独作为模型生成块。重复此过程,直到处理完所有记录:
User.find_each do |user|
NewsLetter.weekly_deliver(user)
end
参考文献:
答案 1 :(得分:12)
是的,Foo.all
。
all
在ActiveRecord :: Relation(例如Foo.where(true)
)上弃用,而不是在ActiveRecord :: Base上。
http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Named/ClassMethods.html#method-i-all
答案 2 :(得分:11)
Rails 4的发行说明:
Model.all现在返回一个ActiveRecord :: Relation,而不是一个数组 的记录。如果你真的想要一个数组,请使用Relation#to_a。
所以你的代码看起来像这样:
Foo.all.to_a.each do |foo|
# whatever
end
请参阅http://guides.rubyonrails.org/4_0_release_notes.html#active-record
答案 3 :(得分:0)
这似乎是Rails中某处不正确的弃用警告。从Rails 4.0.2开始,警告消息仍然存在。当我尝试运行Foo.all时出现以下错误:
DEPRECATION WARNING:不推荐使用Relation#all。如果你想 急切加载关系,你可以调用#load(例如
Post.where(published: true).load
)。如果要从关系中获取记录数组, 你可以拨打#to_a(例如Post.where(published: true).to_a
)。
我几乎100%肯定我在RailsCasts中看到#all被更改为返回Rails 4中的Relation(而不是数组) - 没有提及弃用。