【Rails】 scope は 常に ActiveRecord_Relation を返す素晴らしいやつ
Rails で様々な条件で複合検索ができる画面を実装していて、フォームから受け取った値をそのままモデルに渡してコントローラは条件分岐なしにスッキリ実装したかった。 何の気なしに以下のようなコードを書いた。
Post.hoge_method(params[:hoge]).search(params[:word]).another_method....
例えば search の部分は form から渡ってきた値をモデルに渡して値がなければ その部分のクエリを組み立てないでほしかった。
def self.search(w) if w.present? where('title like :title or description like :description', {title: "%#{w}%", description: "%#{w}%"}) else ... end end
ここで少し思考が停止して、
else のとき、何を返せばいいんだ??となった。
調べてみたら大変素晴らしい記事を見つけた。
【Rails】なぜクラスメソッドよりもスコープを使うべきなのか?
スコープの中で発行されたクエリがnilになる場合は、.allを返すように設計されているので、スコープの返り値を気にせずチェーンを繋げることができます。
そうか。。さっきの部分は
else all end
て書けば良いんだけど scope を使えばその必要すらなくて
scope :search, -> (w) { where('title like :title or description like :description', {title: "%#{w}%", description: "%#{w}%"}) if w.present? }
だけでよいそう。 scope がnilを返したらall ()を返すようになっているのは全然知りませんでした。