オブジェクトIDの空でない配列ids
があり、を使用して対応するオブジェクトを検索するとします。私の印象では、必ずしも。の順序に類似した順序になるとは限りません。Thing
things = Thing.find_all_by_id(ids)
things
ids
私の印象は正しいですか?
find_all_by_id
もしそうなら、順序を維持し、データベースに不必要に何度もヒットしない代わりに、何を使用できますか?
オブジェクトIDの空でない配列ids
があり、を使用して対応するオブジェクトを検索するとします。私の印象では、必ずしも。の順序に類似した順序になるとは限りません。Thing
things = Thing.find_all_by_id(ids)
things
ids
私の印象は正しいですか?
find_all_by_id
もしそうなら、順序を維持し、データベースに不必要に何度もヒットしない代わりに、何を使用できますか?
見てみな:
Thing.where(:id => ids).sort! {|a, b| ids.index(a.id) <=> ids.index(b.id)}
where(:id => ids)
を使用してクエリを生成しますIN()
。次に、並べ替えます。メソッドはクエリ結果を反復処理し、ids配列内のidの位置を比較します。
@ tybro0103の答えは機能しますが、IDの数が多い場合は非効率になります。特に、Array#indexはNで線形です。ハッシュは、次のように大きな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]}
find_all_by_idはrails4で非推奨になっているため、ここで使用しますが、動作は同じです。