With :limit
in query, I will get first N records. What is the easiest way to get last N records?
This question is related to
ruby-on-rails
ruby
activerecord
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.
new way to do it in rails 3.1 is SomeModel.limit(5).order('id desc')
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
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)
Just try:
Model.order("field_for_sort desc").limit(5)
Add an :order parameter to the query
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)
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.
Add an :order parameter to the query
Something.last(5)
because:
Something.last(5).class
=> Array
so:
Something.last(50000).count
will likely blow up your memory or take forever.
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 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".
Just try:
Model.order("field_for_sort desc").limit(5)
we can use Model.last(5)
or Model.limit(5).order(id: :desc)
in rails 5.2
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
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.
Add an :order parameter to the query
new way to do it in rails 3.1 is SomeModel.limit(5).order('id desc')
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 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".
we can use Model.last(5)
or Model.limit(5).order(id: :desc)
in rails 5.2
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
In my rails (rails 4.2)
project, I use
Model.last(10) # get the last 10 record order by id
and it works.
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
In my rails (rails 4.2)
project, I use
Model.last(10) # get the last 10 record order by id
and it works.
Something.last(5)
because:
Something.last(5).class
=> Array
so:
Something.last(50000).count
will likely blow up your memory or take forever.
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.
Add an :order parameter to the query
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|
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.
Source: Stackoverflow.com