Railsでorderの並び順を上書きしたい時はreorderを使用する

default_scopeなどで既にorderが指定されてしまっている時は、reorderでorderの条件を上書きできる。

環境

rails (8.0.2)

使用方法

まずは普通にorderする。

pry(main)> User.order(:id).to_sql
=> "SELECT \"users\".* FROM \"users\" ORDER BY \"users\".\"id\" ASC"

idでorderされていますね。ここでorder(:id)の後ろにorder(:updated_at)を重ねても、条件が追加されるだけです。

pry(main)> User.order(:id).order(:updated_at).to_sql
=> "SELECT \"users\".* FROM \"users\" ORDER BY \"users\".\"id\" ASC, \"users\".\"updated_at\" ASC"

そこで、orderをreorderに変更すると・・・

pry(main)> User.order(:id).reorder(:updated_at).to_sql
=> "SELECT \"users\".* FROM \"users\" ORDER BY \"users\".\"updated_at\" ASC"

無事にidでのorderの条件が上書きされています。
なお、reorderの後にorderを付けると、reorderに条件が追加されます。

pry(main)> User.order(:id).reorder(:updated_at).order(:created_at).to_sql
=> "SELECT \"users\".* FROM \"users\" ORDER BY \"users\".\"updated_at\" ASC, \"users\".\"created_at\" ASC"

reorderの後にreorderを重ねると最後のreorderの条件が適用されます。

pry(main)> User.order(:id).reorder(:updated_at).reorder(:created_at).to_sql
=> "SELECT \"users\".* FROM \"users\" ORDER BY \"users\".\"created_at\" ASC"

default_scopeなどでorderされてしまっているものを打ち消したい時に有効ですが、こういう打ち消し系のメソッドはなるべく使いたくない・・・