joshweir
joshweir

Reputation: 5627

Sort an activerecord result set by another array of ids

How do I order this activerecord result set based on a another array of ids?

I perform an initial query on my activerecord model:

results = Foo.first(5)
results.each do |r| 
  #do some stuff initially with these records. 
  #5 records returned with ids: 1, 2, 3, 4, 5
end 

I then do some further processing which results in another array of ids:

desired_order_ids = [3,1,4,5,2]

I want to order results by Foo.id in the order specified by the desired_order_ids array of ids. How to do this? In reality the above query will retrieve 1000 records, so I am looking for the most memory efficient way to do this?

Upvotes: 2

Views: 1621

Answers (2)

Drenmi
Drenmi

Reputation: 8787

Do you need the end result to be an ActiveRecord::Relation? If you're fine with converting to an Array, this should be the simplest solution:

desired_order_ids.map { |id| results[id - 1] }

Another option could be:

results.sort_by { |result| desired_order_ids.index(result.id) }

Upvotes: 4

zwippie
zwippie

Reputation: 15525

It depends on the DBMS you are using, but I think this will work on most databases:

Foo.all.order('id=3 desc, id=1 desc, id=4 desc, id=5 desc, id=2 desc')

You can use a method to build the argument passed to order like this:

def order_string(field_name, arr)
  arr.map { |val| "#{field_name}=#{val} desc" }.join(', ')
end

and call it like:

Foo.all.order(order_string('id', [3, 1, 4, 5, 2]))

Upvotes: 4

Related Questions