Forum: Ruby on Rails Get a collection using an array of ids, keeping the order

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
73c04e9ef9ca435c5b19a2e765ae6d20?d=identicon&s=25 Max Williams (max-williams)
on 2008-12-04 13:24
Say if i have an array of resource ids, of size n.  Is there a way to
get all the corresponding resources, without doing n individual Find
calls?

eg, i could do this:

@resources = []
array.each{|id| @resources << Resource.find(id)}

But, this requires n Find calls which isn't acceptable.

Any ideas anyone?

thanks
max
81b61875e41eaa58887543635d556fca?d=identicon&s=25 Frederick Cheung (Guest)
on 2008-12-04 13:32
(Received via mailing list)
On 4 Dec 2008, at 12:24, Max Williams wrote:

> But, this requires n Find calls which isn't acceptable.
Resource.find @resources

Fred
81b61875e41eaa58887543635d556fca?d=identicon&s=25 Frederick Cheung (Guest)
on 2008-12-04 13:37
(Received via mailing list)
On 4 Dec 2008, at 12:31, Frederick Cheung wrote:

>> @resources = []
>> array.each{|id| @resources << Resource.find(id)}
>>
>> But, this requires n Find calls which isn't acceptable.
>
> Resource.find @resources
>
Sorry, only read the body of the message, not the subject!
I would sort it after, eg

order_hash = {}
array.each_with_index {|id, index| order_hash[id]=index
Resource.find(array).sort_by {|r| order_hash[r.id]}

Fred
73c04e9ef9ca435c5b19a2e765ae6d20?d=identicon&s=25 Max Williams (max-williams)
on 2008-12-04 13:46
Frederick Cheung wrote:
> On 4 Dec 2008, at 12:31, Frederick Cheung wrote:
>
>>> @resources = []
>>> array.each{|id| @resources << Resource.find(id)}
>>>
>>> But, this requires n Find calls which isn't acceptable.
>>
>> Resource.find @resources
>>
> Sorry, only read the body of the message, not the subject!
> I would sort it after, eg
>
> order_hash = {}
> array.each_with_index {|id, index| order_hash[id]=index
> Resource.find(array).sort_by {|r| order_hash[r.id]}
>
> Fred

ah yes, of course.  Nice touch with the hash (as opposed to sorting by
array.index) :)

Thanks a lot, Fred.
Ef3aa7f7e577ea8cd620462724ddf73b?d=identicon&s=25 Rob Biedenharn (Guest)
on 2008-12-04 14:59
(Received via mailing list)
On Dec 4, 2008, at 7:46 AM, Max Williams wrote:
>> Sorry, only read the body of the message, not the subject!
>
> Thanks a lot, Fred.


YMMV, but why bother with the hash?  Unless you have a truly huge list
of id's

@resources = Resource.find(array).sort_by {|r| array.index(r.id)}

You could even hide the implementation:

class Resource
   def self.find_by_ordered_ids(*array)
     options = {}
     options = array.pop if array.last.is_a? Hash
     # pass an Array or a list of id arguments
     array = array.flatten if array.first.is_a? Array
     find(array, options).sort_by {|r| array.index(r.id)}
   end
end

(Note, untested, but that doesn't mean that it *won't* work ;-)

-Rob

Rob Biedenharn    http://agileconsultingllc.com
Rob@AgileConsultingLLC.com
C64e63b70be7dfed8b0742540b8b27e5?d=identicon&s=25 Mark Reginald James (Guest)
on 2008-12-05 08:19
(Received via mailing list)
If you use MySQL, the "field" function allows you
to retrieve records in a specific id order:

http://groups.google.com/group/rubyonrails-talk/br...

--
Rails Wheels - Find Plugins, List & Sell Plugins -
http://railswheels.com
73c04e9ef9ca435c5b19a2e765ae6d20?d=identicon&s=25 Max Williams (max-williams)
on 2008-12-05 10:23
Mark Reginald James wrote:
> If you use MySQL, the "field" function allows you
> to retrieve records in a specific id order:
>
> 
http://groups.google.com/group/rubyonrails-talk/br...
>
> --
> Rails Wheels - Find Plugins, List & Sell Plugins -
> http://railswheels.com

Ah, now that is a great tip, i'd not seen this before!  Thanks a lot.

The weird thing is, i've gone to my console to try it out, and rails is
now always giving me the resources back in the order of the id array
anyway, whether i use the field option or not.  It's the same with any
of my AR classes!  I'm sure that this didn't used to happen though...i
think i'm going crazy.  Can anyone tell me if this is normal?  If so
then i just imagined this whole problem...

AModel.find([3,1,2]).collect(&:id)
=> [3,1,2]

or do you get

=> [1,2,3]

?
95ac4011d0e657db0c3be18000eaeb36?d=identicon&s=25 Robert Head (robert_head)
on 2010-08-23 04:18
Max Williams wrote:
> The weird thing is, i've gone to my console to try it out, and rails is
> now always giving me the resources back in the order of the id array
> anyway, whether i use the field option or not.  It's the same with any
> of my AR classes!  I'm sure that this didn't used to happen though...i
> think i'm going crazy.  Can anyone tell me if this is normal?

You are not going crazy.

MySQL may, but is not required to, return the objects in the order of
the array.  So, the behavior will change without warning.

You still need to sort after the fetch.
56b7e1808013614acdb73cbaaa6938a1?d=identicon&s=25 Michael Pavling (Guest)
on 2010-08-23 09:39
(Received via mailing list)
On 23 August 2010 03:18, Robert Head <lists@ruby-forum.com> wrote:
> Max Williams wrote:
>> i think i'm going crazy.  Can anyone tell me if this is normal?
>
> You are not going crazy.

I am! This is a reply to a two-year-old thread... I just wasted 10
minutes trying to find out why I hadn't received the previous
messages. I thought my email spam filter was being paranoid :-/
This topic is locked and can not be replied to.