LoginSignup
0
1

More than 3 years have passed since last update.

Railsで検索機能を実装する場合の4つのパターン

Posted at

パターン

  • Ransackを使う
  • コントローラーに書く
  • Concernに書く
  • Formオブジェクトを使う

Ransackを使う

Ransack使うとソートも楽に書けそうだけど、
追々カスタマイズが面倒そうなのもあり最初から自分で書くことが多い。
あまり使ったこと無いので、ケースによっては触ってみたい。

コントローラーに書く

comments = Comment.where(post_id: params[:post_id]) if params[:post_id].present?

こんな感じでコントローラーに直接where文を書くケース。
何も考えずに書くとこうなることが多いと思う。
条件式が増えてくると複雑度上がってrubocopに怒られる。

Concernに書く

module Comments
  module SearchModule
    extend ActiveSupport::Concern

    def self.do_search(params)
     comments = Comment.all
     search_by_post_id(comments, params[:post_id]) if params[:post_id].present?
    end

    def self.search_by_post_id(comments, post_id)
      comments.where(post_id: params[:post_id])
    end
  end
end
Comments::SearchModule.do_search(params)

検索用のConcernモジュールに切り分ける方法。FatControllerはこれで解消できるので良さげ。
ただConcern特有のお作法があるので、自由に書きづらく、単純なクラスが使いたくなった。

Formオブジェクトを使う

class CommentSearchForm < SearchForm
    attribute :post_id, Types::Maybe::Coercible::Integer

    def do_search
     comments = Comment.all
     search_by_post_id(comments, post_id.value_or) if post_id.value_or.present?
    end

    private

    def search_by_post_id(comments, post_id)
      comments.where(post_id: post_id)
    end
end
Dry::Types.load_extensions(:maybe)

module Types
  include Dry::Types.module
end

class SearchForm < Dry::Struct
end
CommentSearchForm.new(params.to_hash.symbolize_keys).do_search

モデルに紐付かないパラメータを処理する時にはVirtusが便利で良く使われているそう。

ただ公式リポジトリをみると作者が後継ライブラリであるdry-rbを推奨していたので、dry-rbを元に実装した。
https://github.com/solnic/virtus

厳密には型指定のみなので以下の3つ。
dry-validationでバリデーションも出来るようなので、後々使ってみたい。

gem 'dry-monads'
gem 'dry-struct'
gem 'dry-types'

普通にgemをインストールすると一番古い0.5系になるので、最新の使い方とは違うので注意。

Formオブジェクトを使ったことで、次のようなメリットがある気がする。
まだ余り使いこなせてないので詳しい方の意見聞きたい。

  • フォーム関連の処理が書かれていることがひと目でわかる
  • FatController対策になる
  • シンプルなクラスでテスト書きやすい
0
1
0

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
0
1