2010-01-25 65 views
3

我正在使用Ruby on Rails/ActiveRecord,并且遇到ActiveRecord#find调用的问题。我在数据库中存储了最近查看的文档ID的序列化数组。这些ID按上次查看时的降序存储,因此最近查看的文档ID在数组中是第一个。该阵列最多包含10个ID。Rails/ActiveRecord:使用ActiveRecord返回订单#find(Array)

到目前为止,这么好。问题在于ActiveRecord#find(Array)似乎忽略了想法在数组中出现的顺序。所以如果我输入Document.find([1,2,3]),我会得到和我做Document.find([3,2,1])相同的结果。

我的问题是这样的:我怎么能得到一个ActiveRecord结果数组,它与我传递给#find的ID的顺序相同?或者,如果ActiveRecord不能直接做到这一点,那么在事实之后如何对结果数组进行排序呢?

非常感谢任何人可以贡献的答案!

回答

11

ActiveRecord是您的数据库的接口,并以与数据库返回它们相同的顺序将记录返回给您。如果您不提供'订单'参数,则返回的订单是(有效)随机的。

如果您的订单是通过编号升序或降序:

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}} 
+0

正是我需要的不是很好,谢谢对于快速和准确的反应非常重要! – David 2010-01-25 02:29:11

+0

真正有趣的技术,这是同时与数据库无关。感谢分享。 – dgilperez 2012-11-08 20:20:57

+0

正是我需要的,为类似的目的 - 最近查看的ID! – idStar 2012-12-05 17:00:34

0

ActiveRecord的使用由底层数据库,这意味着所提供的排序顺序你需要提供一个“ORDER BY”。

要通过ID顺序,你会用

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

这不完全我在找什么,我认为它'这是我的错,因为没有更清楚:问题是ID不总是按升序或降序排列。不过,拉里K.的答案对这种情况很好。 – David 2010-01-25 02:28:48

1

讨论关于做它的分贝侧,对于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 
相关问题