ActiveRecord find_all_by_X是否保留顺序? 如果不是,应该使用什么呢?
假设我有一个非空数组ids
的Thing
对象id,我想使用things = Thing.find_all_by_id(ids)
找到相应的对象。 我的印象是, things
不一定具有类似于ids
的排序。
-
我的印象是否正确?
-
如果是这样,我可以使用什么来代替
find_all_by_id
来保存订单并且不会多次不必要地访问数据库?
- 是
- 使用Array#sort
看看这个:
Thing.where(:id => ids).sort! {|a, b| ids.index(a.id) <=> ids.index(b.id)}
where(:id => ids)
将使用IN()
生成查询。 然后排序! 方法将遍历查询结果并比较ids数组中id的位置。
@ tybro0103的答案会起作用,但对于大量的N来说效率低下。 特别是,Array#index在N中是线性的.Hashing对于大N更好,如在
by_id = Hash[Thing.where(:id => ids).map{|thing| [thing.id, thing]}] ids.map{|i| by_id[i]}
您甚至可以使用此技术通过任何不一定的唯一属性进行任意排序,如
by_att = Thing.where(:att => atts).group_by(&:att) atts.flat_map{|a| by_att[a]}
在rails 4中不推荐使用find_all_by_id,这就是我在这里使用的原因,但行为是相同的。