52

Rails 4 で ActiveRecord::Relation#all が非推奨になった今、すべてのレコードをどのように反復処理すればよいのでしょうか?

以前は次のようでした:

Foo.all.each do |foo|
  # whatever
end

私は今それを近似することができますが、それは汚い感じです:

Foo.where(true).each do |foo|
  # whatever
end

より良い方法はありますか?

4

4 に答える 4

71

Rails Guide on Active Record Query Interfaceによると、すべてのレコードを反復処理する正しい方法は、find_each.

を使用すると、テーブル全体Foo.all.eachがメモリにロードされ、すべての行がインスタンス化されます。次に、インスタンスを反復処理します。これは、メモリ使用量の点でより効率的なバッチで行われます。find_each

ガイドから:

このfind_eachメソッドは、レコードのバッチを取得し、レコードをモデルとしてブロックに個別に生成します。次の例では、find_eachは 1000 レコード ( と の両方の現在のデフォルト) を取得しfind_eachfind_in_batches各レコードを個別にモデルとしてブロックに渡します。このプロセスは、すべてのレコードが処理されるまで繰り返されます。

User.find_each do |user|
  NewsLetter.weekly_deliver(user)
end

参考文献:

于 2013-12-11T23:49:41.813 に答える
15

はいFoo.all

allFoo.where(true)は、ActiveRecord::Base ではなく、ActiveRecord::Relation (例: ) では非推奨です。

http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Named/ClassMethods.html#method-i-all

于 2013-08-11T04:16:30.707 に答える
13

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を参照

于 2014-03-14T22:50:52.520 に答える
0

これは、Rails のどこかで誤った非推奨の警告のようです。Rails 4.0.2 の時点で、警告メッセージはまだ存在します。Foo.all を実行しようとすると、次のエラーが発生します。

非推奨の警告: Relation#all は非推奨です。リレーションをeager-loadしたい場合は、#load (例: Post.where(published: true).load) を呼び出すことができます。リレーションからレコードの配列を取得したい場合は、#to_a を呼び出すことができます (例: Post.where(published: true).to_a)。

Rails 4 で (配列ではなく) Relation を返すように #all が変更されていることを RailsCasts で見たのをほぼ 100% 確信しています。

于 2013-12-11T23:20:18.937 に答える