🙆

ransack でカレンダー検索をしようとして型が原因で機能しなかったこと

2022/03/05に公開

ransack でよくある日付検索を実装しようとした時の原因を書いていこうと思います。

Image from Gyazo

開始日から終了日までに含まれたデータを検索できる様に実装を考えていました。

gteq(greater then or equal to) 〜以上
lteq(less then or equal to) 〜以下

最初これで行けるくね?
と思っていましたが上記の記載ではうまく行きません。

例えば 3/3〜3/5 までのデータが欲しい場合は終了日を 3/6 にしてから検索したいといけません。

3/3 の 0:00〜3/5 の 0:00 でしか検索する事ができないのでこのようなエラーになってしまいました。
3/5 の 23:59:59999....の様に検索する事ができれば欲しい値が取ることができます。

独自のカスタマイズは Ransack の wiki にあるのでここをカスタマイズする必要があります。
(英語の理解が低いのでかなり時間がかかりました。)

ransack の wiki

独自に ransack のカスタマイズを行うときは
ransack.rb は自分で作成を行います。

config/initializers/
├── ransack.rb

ransack.rb
config.add_predicate "lteq_end_of_day", #独自に述語を定義を行える。
  arel_predicate: "lteq", #使用するARel述語をする(eq、matchesなど)
  formatter: proc { |v| v.end_of_day } #入力値のフォーマットを行う

使用する述語名の記載名を行い使用する predicate は lteq を使用して end_of_day メソッドを使用して3/5 の 23:59:59999....の様する事ができます。

end_of_day

日付を時刻 (または必要に応じてDateTime )に変換し、時刻部分を1日の終わり(23:59:59)に設定します

arel

Active Recordの内部で使用されるSQL生成ライブラリ

arelについて

僕が詰まったところは開始日と終了日をDate型で定義していたので上手く登録できませんでしたが
Datetime型に変えてあげることでエラーが解決されました。

あとはビューファイルに記載してあげれば実装できます。

_search.html.slim
  .form-row.w-75.my-3
    .col
      = f.label :start_day_gteq, t('default.start_search')
      = f.date_field :start_day_gteq, include_blank: true, class: 'form-control'
    p.between_start_end 〜
    .col
      = f.label :end_day_lteq_end_of_day, t('default.end_search'),class: 'ml-7'
      = f.date_field :end_day_lteq_end_of_day, include_blank: true, class: 'form-control ml-9'

Discussion