activerecordで最後のN個のレコードを取得する方法は?
-
05-07-2019 - |
質問
クエリで:limit
を使用すると、最初のN個のレコードが取得されます。最後のNレコードを取得する最も簡単な方法は何ですか?
解決
このようなアクティブレコードクエリを使用すると、必要なものが得られます(「Something」はモデル名です):
Something.find(:all, :order => "id desc", :limit => 5).reverse
編集:コメントに記載されているように、別の方法:
result = Something.find(:all, :order => "id desc", :limit => 5)
while !result.empty?
puts result.pop
end
他のヒント
これはRails 3の方法です
SomeModel.last(5) # last 5 records in ascending order
SomeModel.last(5).reverse # last 5 records in descending order
rails 3.1でそれを行う新しい方法は、 SomeModel.limit(5).order( 'id desc')
Rails 4以降のバージョンの場合:
最初の最も古いエントリ
が必要な場合は、このようなものを試すことができますYourModel.order(id: :asc).limit(5).each do |d|
最新のエントリが必要な場合は、このようなものを試すことができます。
YourModel.order(id: :desc).limit(5).each do |d|
解決策はこちら:
SomeModel.last(5).reverse
レールは遅延しているため、最終的には次のようなSQLでデータベースにヒットします。" SELECT table
。* FROM table
ORDER BY table
。 id
DESC LIMIT 5"。
Rails 5(およびおそらくRails 4)の場合
悪い:
Something.last(5)
理由:
Something.last(5).class
=> Array
so:
Something.last(50000).count
おそらくあなたの記憶を爆破するか、永遠にかかります。
適切なアプローチ:
Something.limit(5).order('id desc')
理由:
Something.limit(5).order('id desc').class
=> Image::ActiveRecord_Relation
Something.limit(5).order('id desc').to_sql
=> "SELECT \"somethings\".* FROM \"somethings\" ORDER BY id desc LIMIT 5"
後者は未評価のスコープです。 .to_a
を使用して、連鎖するか、配列に変換できます。だから:
Something.limit(50000).order('id desc').count
...秒かかります。
結果に何らかの順序を設定する必要がある場合は、次を使用します。
Model.order('name desc').limit(n) # n= number
順序付けが不要で、テーブルに保存されたレコードが必要な場合は、次を使用します。
Model.last(n) # n= any number
rails (rails 4.2)
プロジェクトでは、次を使用しています
Model.last(10) # get the last 10 record order by id
そしてそれは動作します。
" pluck"を使用する場合、このクエリの方が優れている/速いことがわかります。好きな方法:
Challenge.limit(5).order('id desc')
これは、出力としてActiveRecordを提供します。次のように.pluckを使用できます:
Challenge.limit(5).order('id desc').pluck(:id)
これにより、最適なSQLコードを使用しながらIDを配列としてすばやく提供します。
試してみてください:
Model.all.order("id asc").limit(5)
モデルにRails 3の昇順を指定するデフォルトスコープがある場合、上記のArthur Nevesで指定されている順序ではなく、並べ替えを使用する必要があります。
Something.limit(5).reorder('id desc')
または
Something.reorder('id desc').limit(5)
N = 5で、モデルが Message
だとすると、次のようなことができます:
Message.order(id: :asc).from(Message.all.order(id: :desc).limit(5), :messages)
SQLを見てください:
SELECT "messages".* FROM (
SELECT "messages".* FROM "messages" ORDER BY "messages"."created_at" DESC LIMIT 5
) messages ORDER BY "messages"."created_at" ASC
キーは副選択です。最初に必要な最後のメッセージを定義する必要があり、次に昇順に並べる必要があります。
クエリに:orderパラメーターを追加します