ActiveRecord::Relation#merge

joinsと組み合わせて使うと関連モデルのスコープが利用できるようになる優れもの。

コード例を見るとわかりやすい。
以下は日記と日記にぶら下がるコメントのモデルを表す

class Diary < ActiveRecord::Base
  has_many :comments
  scope :title_like, lambda {|title|where('title LIKE ?', "%#{title}%")}
end

class Comment < ActiveRecord::Base
  belongs_to :diary
end

この時Commentに対し、親のDiaryのtitleで検索をしたい場合、mergeを使わないと例えば以下のようにる。

class Comment < ActiveRecord::Base
  belongs_to :diary
  scope :diary_title_like,
        lambda {|title| joins(:diary).where('diaries.title LIKE ?', "%#{title}%")}
end

Comment::diary_title_likeとDiary::title_likeはほぼ同じ処理になりDRYではない。


これをmergeを使うと以下のように書く事ができ、titleへのLIKE検索の処理を共通化できる。

class Comment < ActiveRecord::Base
  belongs_to :diary
  scope :diary_title_like,
        lambda {|title| joins(:diary).merge(Diary.title_like(title))}
end