Rails 7.1 adds support for multiple-column ordering in Activerecord
PostgreSQL supports ordering by multiple columns using the ORDER BY clause. The ORDER BY clause allows you to specify a list of columns to sort by, and you can optionally specify whether to sort each column in ascending or descending order.
SELECT *
FROM authors
ORDER BY last_name ASC, first_name DESC;This query will sort the authors table by the last_name column in ascending order
and
then by the first_name column in descending order.
Rails 7.1 adds the above support for specifying the sorting order for each key
within a composite primary key when using ActiveRecord::Batches methods for models.
Before Rails 7.1
Let's assume a Rails application which has an Author model.
For simplicity,
let's say the primary key is set to first_name
and
last_name as shown below:
class Author < ApplicationRecord
self.primary_key = [:first_name, :last_name]
endPrior to Rails 7.1,
when handling batches of records with a composite primary key,
such as first_name
and
last_name,
developers could utilize the :asc
or
:desc argument to regulate the sorting order.
However,
this sorting mechanism had a restriction.
Employing :asc
or :desc to define the sorting order affected both
first_name
and
last_name collectively.
This meant that requesting ascending order sorted both first_name
and
last_name in ascending order together,
and
requesting descending order sorted both columns in descending order together.
You can execute the batch query on the Author model as below:
Author.find_each(order: [:first_name, :last_name]).each do |author|
# your code
endTrying to pass an array [:desc, :asc] to the order clause raises an ArgumentError.
Author.find_each(order: [:desc, :asc]).each do |author|
# your code
end
:order must be :asc or :desc, got [:desc, :asc] (ArgumentError)In Rails 7.1
Rails 7.1 adds support for multiple-column ordering in Activerecord. You can now select the sorting order for each key within a composite primary key.
class Author < ApplicationRecord
self.primary_key = [:first_name, :last_name]
end
Author.find_each(order: [:desc, :asc]).each do |author|
# your code
endThe above code works without raising any argument error.
It sorts the list of authors in descending order by first_name
and
then sorts the result by last_name in ascending order.
The ability to specify sorting orders for composite primary keys extends beyond the
find_each method
and
applies to other batch processing methods offered by ActiveRecord::Batches,
namely find_in_batches
and
in_batches.
These methods enable efficient retrieval
and
processing of records in batches,
similar to find_each.
To know more about this feature, please refer to this PR.