簡體   English   中英

Rails / ActiveRecord:使用ActiveRecord返回順序#find(Array)

[英]Rails/ActiveRecord: Return order with ActiveRecord#find(Array)

我正在使用Ruby on Rails / ActiveRecord,並且在使用ActiveRecord #find調用時遇到問題。 我在數據庫中存儲了最近查看過的文檔ID的序列化數組。 ID按上次查看時的降序存儲,因此最近查看的文檔ID是數組中的第一個。 該陣列最多包含10個ID。

到現在為止還挺好。 問題是ActiveRecord#find(Array)似乎忽略了思想在數組中出現的順序。 因此,如果我鍵入Document.find([1,2,3]),我得到的結果與Document.find([3,2,1])相同。

那么我的問題是:我如何得到一個ActiveRecord結果數組,其順序與我傳遞給#find的ID相同? 或者,如果ActiveRecord不能直接實現這一點,那么如何在事后對生成的數組進行排序?

非常感謝人們可以貢獻的任何答案!

ActiveRecord是數據庫的接口,它按照數據庫返回的順序將記錄返回給您。 如果您不提供“訂單”參數,則返回的訂單(有效)是隨機的。

如果您的訂單是按ID升序或降序:

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

如果id順序不是升序或降序:

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

關於在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's not
[03:28] <RhodiumToad> there is a standard-compliant way of doing it but that's 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

ActiveRecord使用底層數據庫提供的排序順序,這意味着您需要提供“ORDER BY”。

要按ID訂購,您可以使用

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM