When you do Something.find(array_of_ids)
in Rails, the order of the resulting array does not depend on the order of array_of_ids
.
Is there any way to do the find and preserve the order?
ATM I manually sort the records based on order of IDs, but that is kind of lame.
UPD: if it's possible to specify the order using the :order
param and some kind of SQL clause, then how?
Oddly, no one has suggested something like this:
index = Something.find(array_of_ids).group_by(&:id) array_of_ids.map { |i| index[i].first }
As efficient as it gets besides letting SQL backend do it.
Edit: To improve on my own answer, you can also do it like this:
Something.find(array_of_ids).index_by(&:id).slice(*array_of_ids).values
#index_by
and #slice
are pretty handy additions in ActiveSupport for arrays and hashes respectively.
The answer is for mysql only
There is a function in mysql called FIELD()
Here is how you could use it in .find():
>> ids = [100, 1, 6] => [100, 1, 6] >> WordDocument.find(ids).collect(&:id) => [1, 6, 100] >> WordDocument.find(ids, :order => "field(id, #{ids.join(',')})") => [100, 1, 6] For new Version >> WordDocument.where(id: ids).order("field(id, #{ids.join ','})")
Update: This will be removed in Rails 6.1 Rails source code
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With