LoginSignup
10

More than 5 years have passed since last update.

ActiveRecord で merge メソッドの引数に order メソッドを含んだ Relation を渡すと ORDER BY のテーブルが変わってしまう

Last updated at Posted at 2013-10-07

2014.4.7追記 この投稿は Rails 4.0.1の頃のものであり、4.1系では修正済のようです。

次のような Blog と Entry というモデルがあった場合、

class Blog < ActiveRecord::Base
  has_many :entries
end
class Entry < ActiveRecord::Base
  belongs_to :blog
end

以下のように、Blog のmerge メソッドを呼び出すと、Entry の order を呼び出しているのに、発行される SQL は "ORDER BY blogs.udated_at" になってしまう。

irb(main):001:0> Blog.joins(:entries).merge(Entry.order(updated_at: :desc))
  Blog Load (0.2ms)  SELECT "blogs".* FROM "blogs" INNER JOIN "entries" ON "entries"."blog_id" = "blogs"."id" ORDER BY "blogs"."updated_at" DESC
=> #<ActiveRecord::Relation []>

回避するには、order メソッドの引数に文字列でテーブル名を指定する。

irb(main):002:0> Blog.joins(:entries).merge(Entry.order("entries.updated_at DESC"))
  Blog Load (0.6ms)  SELECT "blogs".* FROM "blogs" INNER JOIN "entries" ON "entries"."blog_id" = "blogs"."id" ORDER BY entries.updated_at DESC
=> #<ActiveRecord::Relation []>

特に、再利用目的で scope に order を使用している場合は、冗長でもテーブル名を指定した方がよい。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10