検索条件の入力が複数あるような画面で入力があった条件のみを AND 条件としたい場合、メソッド内に if 文が乱立してしまい、可読性が下がってしまう
そのため、将来的に条件が追加された場合でも、可読性が下がらないようにリファクタリングした内容を備忘録として残しておく

環境

  • ruby: 3.0.5
  • rails: 6.1.7

方法

  • 検索条件をそれぞれ scope に切り出す
    • scope 内で skip 条件を next if で記載する
  • メソッドでそれぞれの scope を呼び出す

前提

検索条件はメソッドの引数として Hash 形式で渡される

実際の例

タイトルと内容で入力があった場合に AND 条件で検索を行い、条件にあった本を取得する
※全ての条件が未入力の場合は全件表示

class Book < ApplicationRecord
  scope :with_title, -> (title) do
    next if title.blank?

    where('title LIKE ?', "%#{title}%")
  end

  scope :with_summary, -> (summary) do
    next if summary.blank?

    where('summary LIKE ?', "%#{summary}%")
  end

  def self.search(options: {})
    with_title(options[:title])
      .with_summary(options[:summary])
  end
end