ActiveRecord find_all_by_X是否保留顺序?如果没有,应该使用什么?

时间:2012-04-05 23:33:51

标签: ruby-on-rails activerecord

假设我有idsThing个对象ID的非空数组,我希望使用things = Thing.find_all_by_id(ids)找到相应的对象。我的印象是,things不一定具有类似于ids的排序。

  1. 我的印象是否正确?

  2. 如果是这样,我可以使用什么代替保留订单的find_all_by_id而不会多次不必要地访问数据库?

2 个答案:

答案 0 :(得分:7)

  1. 使用Array#sort
  2. 检查出来:

    Thing.where(:id => ids).sort! {|a, b| ids.index(a.id) <=> ids.index(b.id)}
    

    where(:id => ids)将使用IN()生成查询。然后排序!方法将遍历查询结果并比较ids数组中id的位置。

答案 1 :(得分:3)

@ tybro0103的答案会起作用,但是对于大量N个ID来说效率低下。特别是,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,这就是我在这里使用的原因,但行为是相同的。