Rails 6.1 supports ORDER BY clause for batch processing methods

Sagar Patil

Sagar Patil

October 22, 2020

This blog is part of our  Rails 6.1 series.

Before Rails 6.1, batch processing methods like find_each, find_in_batches and in_batches didn't support the ORDER BY clause. By default the order was set to id ASC.

1> User.find_each{|user| puts user.inspect}
2
3User Load (0.4ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1000]]

Rails 6.1 now supports ORDER BY id for ActiveRecord batch processing methods like find_each, find_in_batches, and in_batches. This would allow us to retrieve the records in ascending or descending order of ID.

1> User.find_each(order: :desc){|user| puts user.inspect}
2
3User Load (0.4ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT ?  [["LIMIT", 1000]]
1> User.find_in_batches(order: :desc) do |users|
2>   users.each do |user|
3>     puts user.inspect
4>   end
5> end
6
7User Load (0.3ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT ?  [["LIMIT", 1000]]
1> User.in_batches(order: :desc) do |users|
2>   users.each do |user|
3>     puts user.inspect
4>   end
5> end
6
7(0.2ms)  SELECT "users"."id" FROM "users" ORDER BY "users"."id" DESC LIMIT ?  [["LIMIT", 1000]]
8User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ?  [["id", 101]]

Points to remember:

  • The ORDER BY clause only works with the primary key column.
  • Valid values for the ORDER BY clause are [:asc,:desc] and it's case sensitive. If we use caps or title case (like DESC or Asc) then we'll get an ArgumentError as shown below.
1> User.find_in_batches(order: :DESC) do |users|
2>   users.each do |user|
3>     puts user.inspect
4>   end
5> end
6
7Traceback (most recent call last):
8        2: from (irb):5
9        1: from (irb):6:in `rescue in irb_binding'
10ArgumentError (unknown keyword: :order)

Check out the pull request for more details.

If this blog was helpful, check out our full blog archive.

Stay up to date with our blogs.

Subscribe to receive email notifications for new blog posts.