How to get last N records with activerecord?
Ruby on-RailsRubyActiverecordRuby on-Rails Problem Overview
With :limit
in query, I will get first N records. What is the easiest way to get last N records?
Ruby on-Rails Solutions
Solution 1 - Ruby on-Rails
This is the Rails 3 way
SomeModel.last(5) # last 5 records in ascending order
SomeModel.last(5).reverse # last 5 records in descending order
Solution 2 - Ruby on-Rails
Updated Answer (2020)
You can get last N records simply by using last method:
Record.last(N)
Example:
User.last(5)
Returns 5 users in descending order by their id.
Deprecated (Old Answer)
An active record query like this I think would get you what you want ('Something' is the model name):
Something.find(:all, :order => "id desc", :limit => 5).reverse
edit: As noted in the comments, another way:
result = Something.find(:all, :order => "id desc", :limit => 5)
while !result.empty?
puts result.pop
end
Solution 3 - Ruby on-Rails
new way to do it in rails 3.1 is SomeModel.limit(5).order('id desc')
Solution 4 - Ruby on-Rails
For Rails 5 (and likely Rails 4)
Bad:
Something.last(5)
because:
Something.last(5).class
=> Array
so:
Something.last(50000).count
will likely blow up your memory or take forever.
Good approach:
Something.limit(5).order('id desc')
because:
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"
The latter is an unevaluated scope. You can chain it, or convert it to an array via .to_a
. So:
Something.limit(50000).order('id desc').count
... takes a second.
Solution 5 - Ruby on-Rails
For Rails 4 and above version:
You can try something like this If you want first oldest entry
YourModel.order(id: :asc).limit(5).each do |d|
You can try something like this if you want last latest entries..
YourModel.order(id: :desc).limit(5).each do |d|
Solution 6 - Ruby on-Rails
Solution is here:
SomeModel.last(5).reverse
Since rails is lazy, it will eventually hit the database with SQL like: "SELECT table
.* FROM table
ORDER BY table
.id
DESC LIMIT 5".
Solution 7 - Ruby on-Rails
If you need to set some ordering on results then use:
Model.order('name desc').limit(n) # n= number
if you do not need any ordering, and just need records saved in the table then use:
Model.last(n) # n= any number
Solution 8 - Ruby on-Rails
Just try:
Model.order("field_for_sort desc").limit(5)
Solution 9 - Ruby on-Rails
In my rails (rails 4.2)
project, I use
Model.last(10) # get the last 10 record order by id
and it works.
Solution 10 - Ruby on-Rails
we can use Model.last(5)
or Model.limit(5).order(id: :desc)
in rails 5.2
Solution 11 - Ruby on-Rails
I find that this query is better/faster for using the "pluck" method, which I love:
Challenge.limit(5).order('id desc')
This gives an ActiveRecord as the output; so you can use .pluck on it like this:
Challenge.limit(5).order('id desc').pluck(:id)
which quickly gives the ids as an array while using optimal SQL code.
Solution 12 - Ruby on-Rails
Let's say N = 5 and your model is Message
, you can do something like this:
Message.order(id: :asc).from(Message.all.order(id: :desc).limit(5), :messages)
Look at the sql:
SELECT "messages".* FROM (
SELECT "messages".* FROM "messages" ORDER BY "messages"."created_at" DESC LIMIT 5
) messages ORDER BY "messages"."created_at" ASC
The key is the subselect. First we need to define what are the last messages we want and then we have to order them in ascending order.
Solution 13 - Ruby on-Rails
If you have a default scope in your model that specifies an ascending order in Rails 3 you'll need to use reorder rather than order as specified by Arthur Neves above:
Something.limit(5).reorder('id desc')
or
Something.reorder('id desc').limit(5)
Solution 14 - Ruby on-Rails
A simple answer would be:
Model.limit(5).order(id: :desc)
There is a problem with this solution, as id
can't be the sole determiner of when a record was created in the time.
A more reliable solution would be:
Model.order(created_at: :desc).limit(5)
As others have pointed out, one can also use Model.last(5)
. The only gotcha with this is that it returns Array
, and not Model::ActiveRecord_Relation
.
Solution 15 - Ruby on-Rails
Add an :order parameter to the query