How to get last N records with activerecord?

Ruby on-RailsRubyActiverecord

Ruby 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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJtRView Question on Stackoverflow
Solution 1 - Ruby on-RailsBongsView Answer on Stackoverflow
Solution 2 - Ruby on-RailsDan McNevinView Answer on Stackoverflow
Solution 3 - Ruby on-RailsArthur NevesView Answer on Stackoverflow
Solution 4 - Ruby on-RailsAmin ArianaView Answer on Stackoverflow
Solution 5 - Ruby on-RailsGagan GamiView Answer on Stackoverflow
Solution 6 - Ruby on-RailsDeveloperView Answer on Stackoverflow
Solution 7 - Ruby on-RailsThorinView Answer on Stackoverflow
Solution 8 - Ruby on-RailsThorinView Answer on Stackoverflow
Solution 9 - Ruby on-RailstimlentseView Answer on Stackoverflow
Solution 10 - Ruby on-RailsJoydeep BanerjeeView Answer on Stackoverflow
Solution 11 - Ruby on-RailsBrandon MeredithView Answer on Stackoverflow
Solution 12 - Ruby on-RailsMatayoshiMarianoView Answer on Stackoverflow
Solution 13 - Ruby on-RailsscifisamuraiView Answer on Stackoverflow
Solution 14 - Ruby on-RailsArslan AliView Answer on Stackoverflow
Solution 15 - Ruby on-RailsfrankodwyerView Answer on Stackoverflow