Rails 7.1 adds support for multi-column ordering in ActiveRecord::Batches

Navaneeth D

Navaneeth D

October 3, 2023

This blog is part of our  Rails 7 series.

In Rails 7.1, an enhancement has been introduced to ActiveRecord::Batches methods, related to models with composite primary keys. This update allows developers to specify ascending or descending order for each key within a composite primary key.

Before Rails 7.1

In Rails versions prior to 7.1, when batch processing records with a composite primary key, like id_1 and id_2, developers could use the :asc or :desc argument to control the sorting order. However, there was a limitation in how this sorting worked. When you specified the sorting order using :asc or :desc, it affected both id_1 and id_2 simultaneously. In other words, if you requested ascending order, both id_1 and id_2 would be sorted in ascending order together. Similarly, if you requested descending order, both id_1 and id_2 would be sorted in descending order together.

This limitation had practical implications, especially when you needed to sort records by different criteria for each part of the composite primary key.

After Rails 7.1

With the new enhancement in Rails 7.1, developers can now select the sorting order for each key within a composite primary key. Let's see this with an example.

Consider a scenario where you have a Product model with a composite primary key, category_id and product_id. You want to fetch products in descending order of category_id and ascending order of product_id. With Rails 7.1, this becomes straightforward:

class Product < ActiveRecord::Base
  self.primary_key = [:category_id, :product_id]
end

# Retrieving products in descending order of
# category_id and ascending order of product_id
Product.find_each(order: [:desc, :asc]) do |product|
  # Your processing logic for each product goes here
end

The find_each method is a part of ActiveRecord::Batches and is used for efficient batch processing of records from the database. It retrieves records in small batches, reducing memory consumption and improving performance. The method takes an optional order argument, which, as of Rails 7.1, can accept an array of symbols to specify the sorting order for each key within the composite primary key.

The enhancement for specifying sorting orders for composite primary keys is not limited to find_each. It applies to other batch processing methods provided by ActiveRecord::Batches, such as find_in_batches and in_batches. These methods allow you to retrieve and process records in batches efficiently, just like find_each.

Conclusion

In Rails 7.1, the support for multiple-column ordering in batches for models with composite primary keys brings more flexibility and control to your application's data retrieval process. Now you can tailor the sorting of composite keys to match your specific needs, providing a more powerful and versatile toolset for your Rails development endeavors.

Please check out this 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.