Rails7からクエリ結果を任意の順序にする便利なメソッドが追加されていることに気づいたので、Rails7以前と以後での方法をまとめました.
結論
- Rails7以降 - 新たに追加された
in_order_of
を使用. - Rails7以前 - gem 'order_as_specified'の
order_as_specified
を使用.
問題
Active Recordを用いて、以下のようにidの配列の順番にソートしたいケースがある.
users_id = [2, 4, 6, 3, 1]
User.where(id: users_id)
しかし、これでは配列に格納された順番に関係なく、自動的にソートされてしまう.
解決方法
Rails7 以前
gem 'order_as_specified'のorder_as_specified
を使用.
users_id = [2, 4, 6, 3, 1]
User.order_as_specified(id: users_id)
以下のようにArel
などを使ってSQLを記述する方法もあるが、brakemanなどで 'Possible SQL injection' と転けてしまう.
users_id = [2, 4, 6, 3, 1]
order_by = 'CASE '
users_id.each_with_index do |id, index|
order_by << "WHEN id = #{id} THEN #{index} "
end
order_by << 'END'
User.where(id: users_id).order(Arel.sql(order_by))
Rails7 以降
Rails7で新たに追加されたin_order_of
を使用.
users_id = [2, 4, 6, 3, 1]
User.in_order_of(:id, users_id)
これでgemを入れる必要はなくなりました.