LoginSignup
6
7

More than 5 years have passed since last update.

ActiveAdminで検索条件をカスタムする方法

Last updated at Posted at 2015-07-28

実現したいこと

検索条件に何も指定しない場合に、NULLのデータのみ検索結果に表示したい
同一フォームで、「文字列が含まれている」、「文字列が等しい」、「文字列が空」で検索したい

問題

ActiveAdminのfilterは、なにか文字列が含まれていないと検索条件に含むことができない(where句に追加されない)

解決策

検索条件に未設定の文字列があったら、nilに変換する。これを実現するために、Ransackのcustom_predicateを作成する

設定ファイルに追加

config/initializers/ransack.rb
Ransack.configure do |config|
  config.add_predicate 'equals_or_empty',
    arel_predicate: 'eq',
    formatter: proc { |v|
      v == '未設定' ? nil : v
    },
    validator: proc { |v| v.present? },
    compounds: true,
    type: :string
end

ActiveAdmin Controllerに追加

app/admin/example.rb
filter :name, filters: ['contains', 'equals_or_empty']
app/admin/example.rb
ActiveAdmin.register Example do
  index do
    column :name do |example|
      if example.name.present?
        example.name
      else
        "未設定"
      end
    end
end

(Exampleは、適当なモデル名に読み替える)

containsは、適当な文字列で検索、equals_or_emptyは、未設定ならnullのデータを、未設定以外の文字列なら、通常のequalsと同じ動きをする

ロケールに追加

config/locales/activeadmin.ja.yml
---
ja:
  active_admin:
    filters:
        equals_or_empty: "等しい"

filtersに、equalsの代わりに自分で作成したequals_or_emptyを指定する。
eq(equals)と同じ名前にしておいた

余談

本当は、フォームに何も入力されていない場合にnilを設定するようにしたい。もしもっといい方法があればコメントが欲しいです。

最初、ransackerを使ってみたが、filtersで指定した条件でcondisionを決まるため、equalsを指定した場合にname = "", containsを指定した場合にname LIKE "%value%"になってしまう。入力文字列に合わせてname is nullや、name LIKE "%%"`をしたかったができなかった。どこかにArelを上書きするポイントがないものか、、

参考

6
7
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
6
7