【Rails】custom predicateについて(ransack)
はじめに
ransackのcustom predicateとは、name_eqやname_contのeqやcontなどのpredicate(述語)をカスタマイズして、自由に設定できるものです。
実装
まず、config/initializers下にransack.rbファイルを作成しましょう。
公式ドキュメントに下記の記載方法がのっています。
# config/initializers/ransack.rb Ransack.configure do |config| config.add_predicate 'equals_diddly', # Name your predicate # What non-compound ARel predicate will it use? (eq, matches, etc) arel_predicate: 'eq', # Format incoming values as you see fit. (Default: Don't do formatting) formatter: proc { |v| "#{v}-diddly" }, # Validate a value. An "invalid" value won't be used in a search. # Below is default. validator: proc { |v| v.present? }, # Should compounds be created? Will use the compound (any/all) version # of the arel_predicate to create a corresponding any/all version of # your predicate. (Default: true) compounds: true, # Force a specific column type for type-casting of supplied values. # (Default: use type from DB column) type: :string, # Use LOWER(column on database). # (Default: false) case_insensitive: true end
一つずつ解説していきます。
# こちらでブロックを作ります。 Ransack.configure do |config| #ここでpredicateの名前を決めています。これを実際のビューとかで使われるわけですね。 config.add_predicate 'equals_diddly' # どんな動きをするかを指定 arel_predicate: 'eq' # vが検索されて受け取る値になります。{ |v| "#{v}-diddly" }このブロック内で自分で自由にフォーマットを変えることができます。 formatter: proc { |v| "#{v}-diddly" } # こちらでバリデーションを決めています。 validator: proc { |v| v.present? } # これは恐らく複数のarel_predicateの組み合わせをtrueにするかということだと思います。デフォルトはtrueなので、特にあまりいじらなくて良いかと思います。 compounds: true # stringやintegerなどのタイプを指定します。 type: :string # 大文字、小文字の区別をする設定です。デフォルトはfalseです。 case_insensitive: true
このような記法で設定していきます。
例えば、
作成日の範囲指定では、掲示板の作成日に対して「◯◯月◯◯日〜◯◯月◯◯日」という検索をかけたいとき、
<%= f.date_field :created_at_gteq, class: 'form-control' %> 〜 <%= f.date_field :created_at_lteq, class: 'form-control' %>
これでは、1/1〜1/31日の午前0時まで間しか検索できません。
よって、lteqをカスタマイズします。
ransack.rb
Ransack.configure do |config| config.add_predicate 'lteq_end_of_day', # 述語の名前 arel_predicate: 'lteq', #lteqを使用 formatter: proc { |v| v.end_of_day } #上記のものをカスタマイズ end
これで
<%= f.date_field :created_at_gteq, class: 'form-control' %> 〜 <%= f.date_field :created_at_lteq_end_of_day, class: 'form-control' %>
と実装すれば、1/1から1/31日23時59分までの検索をすることができます。