Rails / ActiveRecord: return order with ActiveRecord # find (array)

I am using Ruby on Rails / ActiveRecord and am having trouble calling ActiveRecord # find. I store in the database a serialized array of recently viewed document identifiers. Identifiers are stored in descending order when they were last viewed, so the most recently viewed document identifier is the first in the array. The array includes a maximum of 10 identifiers.

So far so good. The problem is that ActiveRecord # find (Array) seems to ignore the order in which ideas appear in the array. Therefore, if I type Document.find ([1, 2, 3]), I get the same result as Document.find ([3, 2, 1]).

So my question is this: how can I get an array of ActiveRecord results that is in the same order as the identifiers I passed #find? Or, if ActiveRecord does not make this possible directly, how can I sort the resulting array after the fact?

Thanks so much for any answers people can make!

+3
source share
3 answers

ActiveRecord is an interface to your database and returns records to you in the same order as the database. If you do not specify the order parameter, then the returned order is (efficiently) random.

If your order is by name or descending:

results = SomeModelName.find([1,2,3], :order => "id") # ascending order
results = SomeModelName.find([1,2,3], :order => "id desc") # descending order

If the order id does not increase or descend:

ids = [1, 3, 2]
r = SomeModelName.find(ids)
results = ids.map{|id| r.detect{|each| each.id == id}}
+11
source

, db, rails: (

[03:24] <brauliobo> how can I select ids in an specified order? i would like to do something like "select * from blocks where id in (349120, 349118, 349117) order by id (349120, 349118, 349117)", but the order return is the db order.
[03:25] <RhodiumToad> if you have only a few ids you can do this:
[03:26] <RhodiumToad> select * from blocks where id in (349120, 349118, 349117) order by id <> 349120, id <> 349118, id <> 349117;
[03:26] <RhodiumToad> if you have more you may prefer this:
[03:27] <RhodiumToad> select * from blocks join (select i, (ARRAY[349120, 349118, 349117])[i] as id from generate_series(1,3) i) s on (s.id=blocks.id) order by s.i;
[03:27] <brauliobo> nice, it is a lot of ids
[03:28] <brauliobo> do you think this second query is "cross" sql compliant?
[03:28] <RhodiumToad> no, it not
[03:28] <RhodiumToad> there is a standard-compliant way of doing it but that still not supported by most of the dbs you're likely to use other than postgres
[03:29] <brauliobo> so this is the standard-compliant way?
[03:29] <RhodiumToad> no
[03:30] <RhodiumToad> generate_series is not in the standard
[03:30] <RhodiumToad> the standard way would be something like this:
[03:31] <RhodiumToad> select * from blocks join unnest(array[349120, 349118, 349117]) with ordinality as u(id,i) on (blocks.id=u.id) order by u.i;  but pg does not yet support the "with ordinality" clause
[03:32] <brauliobo> interesting, which sql standard it it?
[03:34] <RhodiumToad> 2008
+1

ActiveRecord uses the sort order provided by the underlying database, which means you need to provide "ORDER BY".

To order by ID, you must use

find(:all, :order => "id")
0
source

Source: https://habr.com/ru/post/1729839/


All Articles