しおブログ言うてますけど

技術ブログ言うてますけど技術以外のことも発信すると思われ。RubyとかRuby on Railsとか生き方とかジャンルにこだわらず自分の好きなように。初心者なのでお手柔らかに。

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_gteqcreated_at_lteqの場合、「1月1日00時〜1月5日00時」までのリストしか表示することができません。
これでは困ります。実質前日のリストしか検索できないようになってますね。

ransackのカスタマイズ

ransackは非常に便利なので、カスタマイズすることによって検索条件を変更することができます。
どうやってカスタマイズしたらいいのか。
predecatesをカスタマイズすることで検索条件を変更することができます。
predicateを直訳すると述語
検索するとき、「attribute(属性) + predicate(述語)」で検索しますよね。

<%= f.search_field :name_cont %>

このようなコードの場合、name(属性)+cont(述語)というふうにすることで、name属性に~を含んでいるものを検索対象としています。
このcontという部分がpredicate。つまり述語になります。

github.com

上記の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としています。 どのようになってるか見てみましょう。

https://i.gyazo.com/48db56414b15236d1a0ba45496031152.png

こんなふうになっており、「いつ~いつ」という検索ができるようになっていますね。

まとめ

  • ransackでカスタマイズするときは、config/initializers/ransack.rbを作成し、ransack公式Github内のWikiを参考にカスタマイズする。
    ransack.rbのconfigのコードが最初よくわからなかったが、config.add_predicateではカスタマイズするpredicateの名前を設定する。つまり名前を設定していて、arel_predicateで実際にカスタマイズするpredicateを設定しているということに気づいてだいぶ整理しやすくなった。
    アウトプットって大事やな... 最後まで拝読していただきありがとうございました。