1

I have two objects.

  1. ActiveRecord Collection
  2. Hash with a number, record id pair

Example Hash: { 1=>10145, 2=>11543, 3=>50, 4=> 77534 }

So, I want to order my ActiveRecord query based on the key in my hash for the corresponding record id as it's value. How can I go about doing this?

daveomcd
  • 6,367
  • 14
  • 83
  • 137
  • How about turning your hash into an array and they sorting on that? The Googles provide a number of examples on how to do that (the second part, the first part is simple enough) including [here](https://stackoverflow.com/questions/1680627/activerecord-findarray-of-ids-preserving-order/26868980#26868980). – jvillian Jan 17 '18 at 20:24
  • 1
    [this](https://stackoverflow.com/a/48130387/63034) should do the trick with a couple of minor modifications. – mikej Jan 17 '18 at 20:49

3 Answers3

0

Your data structure to store the ranking/order could be improved. Something like,

{ record_id => order }

You can generate 1 by doing this

sorted_hash = hash.sort { |a, b| a.first <=> b.first }.each_with_object({}) { |a, m| m[a.last] = a.first }

ar_collection is your ActiveRecord collection.

ar_collection.sort { |a, b| sorted_hash[a.id] <=> sorted_hash[b.id] }

Your hash might be missing some data, ex. record id: 100, is not part of the hash.

So you can avoid the exception as such:

ar_collection.sort { |a, b| sorted_hash[a.id] || 0 <=> sorted_hash[b.id] || 0 }

The missing ranking, will be at the top.

0

Based off of @jvillian's comment I ended up with a pretty simple solution that works.

record_ids = People.where(:position_id: 5).order(:last_name, :first_name).pluck(:id)
# Pass ids to my Active Job, and then finally in the partial do the following ...
People.where(id: record_ids).sort_by {|record| record_ids.index record.id }

Thanks!

daveomcd
  • 6,367
  • 14
  • 83
  • 137
0
order_hash = { 1 => 10145, 2 => 11543, 3 => 50, 4 => 77534 }
User.find(order_hash.values)
Sergio Belevskij
  • 2,478
  • 25
  • 24
  • ["The returned records may not be in the same order as the ids you provide since database rows are unordered"](http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-find) so just a `find` call isn't enough to get the desired order. – mu is too short Jan 17 '18 at 23:35
  • Thank you for this code snippet, which might provide some limited short-term help. A proper explanation would greatly improve its long-term value by showing why this is a good solution to the problem, and would make it more useful to future readers with other, similar questions. Please edit your answer to add some explanation, including the assumptions you've made – Shawn C. Jan 18 '18 at 04:26