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.