Rails Added Filter Option On in_order_of Method

The in_order_of method allows developers to retrieve records in a specified order based on a given list of values.

It uses the where clause to filter the results only with the values specified in values.

It is particularly useful when the desired order is not strictly alphabetical or numerical but rather custom-defined.

The recent PR introduces the filter option to the in_order_of method, allowing for even more flexibility.

By default, filter is set to true, which means only the specified values are included in the result. When filter is set to false, all records are included, with the specified values prioritized.

Before

Prior to the implementation of this feature, the method returned only the filtered values.

Let’s take an example to understand the behavior better

Suppose we have an Invoice model with the following records:

# invoices table: id, status
Invoice.create(id: 1, status: "sent")
Invoice.create(id: 2, status: "paid")
Invoice.create(id: 3, status: "draft")
Invoice.create(id: 4, status: "overdue")
Invoice.create(id: 5, status: "sent")

Now consider a scenario where we want to fetch invoices with sent status first, followed by draft invoices. The code for it will look like this:

invoices = Invoice.in_order_of(:status, ["sent","draft"]).pluck(:id)

# Output:
# [1, 5, 3]

# SELECT "invoices"."id" FROM "invoices"
# WHERE "invoices"."status" IN (1, 0) ORDER BY CASE 
#   WHEN "invoices"."status" = 1 THEN 1 
#   WHEN "invoices"."status" = 0 THEN 2 
# END ASC

Now the above code only returns the ids of the specified status and if we wanted to include all the status in the result then we would have to write custom logic for it.

After

With the filter option, this becomes straightforward

invoices = Invoice.in_order_of(:status, ["sent","draft"], filter: false).pluck(:id)

# Output:
# [1, 5, 3, 2, 4]

# SELECT "invoices"."id" FROM "invoices"
# ORDER BY CASE 
#   WHEN "invoices"."status" = 'sent' THEN 1 
#   WHEN "invoices"."status" = 'draft' THEN 2
#   ELSE 3 
# END ASC

The above code prioritizes the sent and draft status first and then included all the records.

To know more about this feature, please refer to this PR

Need help on your Ruby on Rails or React project?

Join Our Newsletter