LoginSignup
11
12

More than 5 years have passed since last update.

ActiveAdminで日付+時刻検索する

Posted at

悶絶したのでメモ。DBはPostgresです

例えばcreated_atのようにtimestampsのフィールドを日付と時刻それぞれで条件かけて検索したい場合を考える。

filter :created_at

↑の書き方だとデータ型のおかげでdate_rangeであることは認識してくれるがこれだけだと時刻で検索ができない。
考え方としては、

  • 日付と時刻を別々にfilterすることを考える
  • 日付・時刻検索用のRansackerを定義する
  • filterにRansackerを適用する

というアプローチが必要になる。

model.rb
  ransacker :created_date do
    Arel.sql("to_char(created_at, 'YYYY-MM-DD')")
  end

  ransacker :created_time do
    Arel.sql("to_char(created_at, 'HH24-MI-SS')")
  end

↑モデルにransackerを定義する。
ransackerは検索条件が複雑な場合や、もともとカラムに入っていないものを検索したい場合に定義するとよいとのこと。この場合はcreated_dateとcreated_timeで日付と時刻を別々に定義する。
ちなみに、ブロックの中はArelで書かなければならないらしい。試しにsqueelで書いたら動作しなかった。

activeadmin_model.rb
#created_times = -> { 日付の文字列形式の配列を返す }

filter :created_date, label: "作成日付", as: :date_range
filter :created_time_gteq, label: "作成時刻(最小)", as: :select, collection: created_times
filter :created_time_lteq, label: "作成時刻(最大)", as: :select, collection: created_times

↑ActiveAdmin側の例。日付に関してはcreated_dateのfilterで同名のransackerを引っ張ってきてdate_rangeの形で表示する。

時刻のフィルタリングに関してはcreated_time_gteqcreated_time_lteqの2つのフィルターで範囲を定義する。
created_time_gteqのfilterはプルダウンの表示項目にはcreated_timesという名前でラムダ式を使用している。
マスターから引っ張ってくるなりRubyでロジック書くなりして"0:00"から"23:30"までの文字列を配列で返す式を書けば良い。
プルダウンの値はフィルタリングする際の検索条件になる。
この場合created_time_gteqのプルダウンに"8:00"と書けばモデルの検索条件にcreated_time >= '8:00'が追加される。もちろん、created_timeの定義はransackerから与えられて勝手に補ってくれる。
filter名の接尾辞で検索条件を指定できる。この場合gteqで≧、lteqで≦であり、他にもパターンがありそう。

このフィルターを使うと以下のようなSQLが発行される。

SELECT  "tables".* FROM "tables" 
WHERE  (to_char(created_at, 'YYYY-MM-DD') >= '2015-06-01' 
AND to_char(created_at, 'YYYY-MM-DD') <= '2015-07-01' 
AND to_char(created_at, 'HH24-MI-SS') >= '04:30' 
AND to_char(created_at, 'HH24-MI-SS') <= '08:30')  
ORDER BY "tables"."id" desc LIMIT 30 OFFSET 0

ransackerは作りがかなりメタいうえにfilterとどう関連づくのかを理解するのが大変だった。ドキュメントの記述がいまいち理解できなかったため試行錯誤で強引に辿り着いたところがある。

公式にも様々な例があり、複雑なのでちょっと目を通しただけだとわけわからないが使いこなすと色々できそうである。

11
12
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
11
12