ActiveRecord::Batches module provides methods like find_each, find_in_batches,
and in_batches to process records in batches, reducing memory consumption.
By default, records are processed in ascending order by primary key(ID).
# default asc order
User.find_each do |user|
puts user.id
end
User Load (0.4ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 1000]]
1
2
3Before
Before Rails 7.1, ActiveRecord::Batches methods - like find_each, find_in_batches,
and in_batches supported ORDER BY the primary key (ID) in either ascending or descending order.
class User < ApplicationRecord
self.primary_key = [:first_name, :last_name]
end# Before Rails 7.1, trying to pass an array [:desc, :asc] to the order clause raised ArgumentError
User.find_each(order: [:asc, :desc]) do |user|
puts "#{user.first_name} #{user.last_name}"
end
:order must be :asc or :desc, got [:asc, :desc] (ArgumentError) We could only specify a single sorting direction (:asc or :desc) as it only supported ORDER BY on single primary column.
This restriction made it impossible to sort by multiple columns, such as having one column in ascending order while sorting another column in descending order, as ActiveRecord::Batches did not support multi-column ordering.
After
Rails 7.1 adds support for batching using composite primary keys and multiple column ordering.
It allows selection of ascending or descending order for each key in composite primary key.
By default the order is set to ASC. Valid values for the ORDER BY clause are :asc or :desc or an array consisting of :asc or :desc
and it’s case sensitive.
class User < ApplicationRecord
self.primary_key = [:first_name, :last_name]
end# Users in ascending order of first_name and descending order of last_name
User.find_each(order: [:asc, :desc]) do |user|
puts "#{user.first_name} #{user.last_name}"
end
User Load (1.7ms) SELECT "users".* FROM "users" ORDER BY "users"."first_name" ASC, "users"."last_name" DESC LIMIT $1 [["LIMIT", 1000]]
Book Keeper
Oliver Smith
Sam Smith
Sam Admin
Varun AgarwalPassing anything other than :asc, :desc raises ArgumentError
raise ArgumentError, ":order must be :asc or :desc or an array consisting of :asc or :desc, got #{order.inspect}"