Rails 7 adds `Enumerable#in_order_of` to put an enumerable in a certain order by a key.


Rails 7 has added a method called in_order_of in enumerable that returns a new array ordered according to the provided series. Order series should be based on the key of the objects in the original enumerable.

Before

Let’s say we have a User struct with id and name attributes.

User = Struct.new(:id, :name)
users = [User.new(1, "Alex"), User.new(6, "Sam"), User.new(4, "Roy")]

If we want to get the users in order of ids as [6, 1, 4], we would have to add a custom method as shown below

id_order = [6, 1, 4]

users.sort_by{ |x| id_order.index x['id'] }
=> [#<struct User id=6, name="Sam">, #<struct User id=1, name="Alex">, #<struct User id=4, name="Roy">]

After

With the changes in Rails 7, we can replace the above custom code with in_order_of as below

users.in_order_of(:id, [6, 1, 4])
=> [#<struct User id=6, name="Sam">, #<struct User id=1, name="Alex">, #<struct User id=4, name="Roy">]

Similarly, we can order on basis of name attribute as well.

users.in_order_of(:name, ["Roy", "Alex", "Sam"])
=> [#<struct User id=4, name="Roy">, #<struct User id=1, name="Alex">, #<struct User id=6, name="Sam">]

Notes:

  • If the series include values that have no corresponding record in the Enumerable, they are ignored and, the rest will be returned.
users.in_order_of(:id, [6, 1, 8, 4])
=> [#<struct User id=6, name="Sam">, #<struct User id=1, name="Alex">, #<struct User id=4, name="Roy">]

# There is no User corresponding to id: 8, so it is ignored.
  • If the Enumerable has additional elements that aren’t included in the series then those will be ignored in the result.
users.in_order_of(:id, [6, 4])
=> [#<struct User id=6, name="Sam">, #<struct User id=4, name="Roy">]

# The series does not have id: 1, so the resultant enumerable does not
# have the record.