ransackで「いつ~いつ」を検索するためのカスタマイズ方法
こんにちはしおはまです。
今回はransack
というGemを使って「いつ~いつ」という条件で検索できるようにするためのカスタマイズ方法についてまとめていきたいと思います。
基本的な検索方法については別の記事で紹介しておりますのでそちらを参照してください。
前提条件
今回実装するための前提条件として、ToDoアプリを作ったとして、そのToDoアプリのリストの作成日時を「いつ~いつ」という条件で検索できるようにしたいという構成になってます。
List
モデルのcreated_at
を検索対象としています。
もちろん今回使用するransack
というGemは導入している前提です。
それでは実装方法についてまとめていきます。
簡単なやり方
一番簡単な実装方法はlistcontroller
にて
@q = List.ransack(params[:q]) @lists = @q.result.includes(%i[user]).order(created_at: :asc)
として検索できるようにします。
viewにて
<%= f.label :created_at_gteq %> <%= f.text_field :created_at_gteq %> <%= f.label :created_at_lteq %> <%= f.text_field :created_at_lteq %>
とすることによって「いつ~いつ」という条件の検索ができるようになります。
しかし、この実装方法では正しく絞り込みができません。
例えば、1月1日から1月5日までのリストを検索したい場合、「xx(年)/1/1」~「xx(年)/1/5」と検索フォームに入力します。
created_at_gteq
とcreated_at_lteq
の場合、「1月1日00時〜1月5日00時」までのリストしか表示することができません。
これでは困ります。実質前日のリストしか検索できないようになってますね。
ransackのカスタマイズ
ransackは非常に便利なので、カスタマイズすることによって検索条件を変更することができます。
どうやってカスタマイズしたらいいのか。
predecates
をカスタマイズすることで検索条件を変更することができます。
predicate
を直訳すると述語。
検索するとき、「attribute(属性) + predicate(述語)」で検索しますよね。
<%= f.search_field :name_cont %>
このようなコードの場合、name(属性)+cont(述語)というふうにすることで、name属性に~を含んでいるものを検索対象としています。
このcont
という部分がpredicate
。つまり述語になります。
上記のURLはransackの公式Github内のWikiにここをカスタマイズするよ~的なことが書いてあるURLです。
このまま全部コピペして、みたいなことはしなくてよくて、カスタマイズしたい部分だけコードを書けばいいです。
config/initializers/ransack.rbを作成して、カスタマイズしていきます。
Ransack.configure do |config| config.add_predicate 'lteq_end_of_day', arel_predicate: 'lteq', formatter: proc { |v| v.end_of_day } end
この辺りはransackの公式Githubを見たほうがわかりやすいですが、1つずつ見ていきます。
config.add_predicate
→ 述語の名称。ここでカスタマイズするpredicateの名前を設定します。
arel_predicate
→入力された値を適切にフォーマットする。ここでカスタマイズするpredicateを記載します。今回はcreated_at_lteq
のpredicateであるlteq
をカスタマイズしたいので引数にlteq
を取ります。
formatter: proc
→値を検証します。無効な値は、検索に使用されません。 ここで受け取った値をどうフォーマットするかを変更できます。
デフォルトでは{ |v| "#{v}-diddly" }
となっています。
今回はend_of_dayで受け取るように設定しています。
viewの設定
ここまで設定できたらviewの設定をしていきます。
<%= f.date_field :created_at_gteq, include_blank: true, class: 'form-control', , placeholder: '年/月/日' %> <%= f.date_field :created_at_lteq_end_of_day, include_blank: true, class: 'form-control', , placeholder: '年/月/日' %>
今回、lteq_end_of_dayというpredicateを設定したので「いつ~いつ」という検索条件の「いつまで」の部分にcreated_at_lteq_end_of_day
としています。
どのようになってるか見てみましょう。
こんなふうになっており、「いつ~いつ」という検索ができるようになっていますね。