Using array_position to Sort ActiveRecord Records By Array

Fruit

In Ruby on Rails, you may face the issue when you try to use .where with array but your expected result is sorted by your input array. Because in Rails the result of .where is sorted by id in default.

In this blog post, I’m going to share quick tips by using array_position to get your result sorted by input array.

Here is the data we prepared for demonstration of using array_position. A table called fruits with five different of fruit.

#<ActiveRecord::Relation [
 #<Fruit id: 1, name: "Apple", quantity: 20, created_at: "2021-09-12 16:33:55", updated_at: "2021-09-12 16:33:55">,
 #<Fruit id: 2, name: "Orange", quantity: 10, created_at: "2021-09-12 16:34:07", updated_at: "2021-09-12 16:34:07">,
 #<Fruit id: 3, name: "Watermelon", quantity: 30, created_at: "2021-09-12 16:34:32", updated_at: "2021-09-12 16:34:32">,
 #<Fruit id: 4, name: "Banana", quantity: 40, created_at: "2021-09-12 16:34:49", updated_at: "2021-09-12 16:34:49">,
 #<Fruit id: 5, name: "Kiwi Fruit", quantity: 50, created_at: "2021-09-12 16:35:05", updated_at: "2021-09-12 16:35:05">
]>

First, we are using this ruby code to query these three fruits. Banana, Kiwi Fruit and Orange.
Fruit.where(name: ["Banana", "Kiwi Fruit", "Orange"])
and here is the result

#<ActiveRecord::Relation [
 #<Fruit id: 2, name: "Orange", quantity: 10, created_at: "2021-09-12 16:34:07", updated_at: "2021-09-12 16:34:07">,
 #<Fruit id: 4, name: "Banana", quantity: 40, created_at: "2021-09-12 16:34:49", updated_at: "2021-09-12 16:34:49">,
 #<Fruit id: 5, name: "Kiwi Fruit", quantity: 50, created_at: "2021-09-12 16:35:05", updated_at: "2021-09-12 16:35:05">
]>

You can see that even your input array is ["Banana", "Kiwi Fruit", "Orange"] but the result is sorted by ID. Is there a way to sort the result by the input array? You can use array_position. We can just make a smaller change to achieve.

fruits = ["Banana", "Kiwi Fruit", "Orange"]

# fruits.map { |x| "'#{x}'" }.join(',') used to convert array to string 'Banana', 'Kiwi Fruit', 'Orange'
Fruit.where(name: fruits).order("array_position(ARRAY[#{fruits.map { |x| "'#{x}'" }.join(',')}], name::TEXT)")

Here is the ActiveRecord result

#<ActiveRecord::Relation [
 #<Fruit id: 4, name: "Banana", quantity: 40, created_at: "2021-09-12 16:34:49", updated_at: "2021-09-12 16:34:49">,
 #<Fruit id: 5, name: "Kiwi Fruit", quantity: 50, created_at: "2021-09-12 16:35:05", updated_at: "2021-09-12 16:35:05">,
 #<Fruit id: 2, name: "Orange", quantity: 10, created_at: "2021-09-12 16:34:07", updated_at: "2021-09-12 16:34:07">
]>

as you can see you can use array_position to sort the record by array.

What if I’m using MySQL?

you can use field to sort the result

fruits = ["Banana", "Kiwi Fruit", "Orange"]
Fruit.where(name: fruits).order("field(name, #{fruits.join(',')})")

The post Using array_position to Sort ActiveRecord Records By Array appeared first on CoinGecko Blog.

You May Also Like