指定した順序どおりにレコードを取得する
作業環境
使用しているRailsは4.1.1です。
$ rails -v Rails 4.1.1
一番手っ取り早い方法
例えば、ユーザを指定のid順に取得したい場合は、
# 普通にid渡してもできない user_ids = [4,2,3,1] users = User.where(id: user_ids) #=> [1,2,3,4] # MysqlのOREDER BY FIELD句を使う user_ids = [4,2,3,1] users = User.where(id: user_ids).order("FIELD(id, #{user_ids.join(',')})") #=> [4,2,3,1]
クラスを拡張する方法
頻繁に使用する場合はクラスを拡張して利用したほうがいいと思います。
module Extensions::ActiveRecord::FindByOrderedIds extend ActiveSupport::Concern module ClassMethods def find_ordered(ids) order_clause = "CASE id " ids.each_with_index do |id, index| order_clause << sanitize_sql_array(["WHEN ? THEN ? ", id, index]) end order_clause << sanitize_sql_array(["ELSE ? END", ids.length]) where(id: ids).order(order_clause) end end end ActiveRecord::Base.include(Extensions::ActiveRecord::FindByOrderedIds) Person.find_ordered([2, 1, 3]) # => [2, 1, 3]
How to select database records in an arbitrary order - Justin Weiss より抜粋
ちなみに
Railsのmasterにはこの手のメソッドが組み込まれているそうです。
Model.where(id: ids).order(['field(id, ?)', ids])