Active Adminの検索条件にenum値が反映されない現象が発生する。
現象詳細
enum値は以下の通り。
enum status: { not_started: 0, in_progress: 1, done: 9 }
Active Admin内のfilter設定は以下の通り。(enum値の日本語化対応も込み)
filter :status, as: :select, collection:Inquiry.statuses_i18n.invert
この時に検索条件にenum値の選択項目が表示されるものの、絞り込みが動作しない現象が発生する。
原因
activeadminの検索にはransack gemを使用してが、ransackがうまくenumに対応できていないことが原因。
以下のように変更すると正しく動作する。
filter :status, as: :select, collection:Inquiry.statuses_i18n.invert.map{ |k, v| [k, Inquiry.statuses[v]]}
原因詳細
filter :status, as: :select, collection:Inquiry.statuses_i18n.invert
上記フィルターを指定した際に、サーバへ送付されるパラメータは以下のようになる。
{"q"=>{"status_eq"=>"in_progress"}, "commit"=>"絞り込む", "order"=>"id_desc"}
これを受けて、本来は、in_prgressに対応した1で検索をしてほしいが、実際のSQLを見ると以下のように'status'=0となっている。
SELECT COUNT(*) FROM (SELECT 1 AS one FROM `inquiries` WHERE `inquiries`.`status` = 0 LIMIT 30 OFFSET 0) subquery_for_count
つまりransack側でin_progress → 1という変換を期待してたがenumの値をとってくれず、
数値にカラムに文字列を指定したので、0が指定された。
解決方法
filterに指定したcollection:以降の部分は、コンソールで叩くと以下のようになる。
>Inquiry.statuses_i18n.invert
{"未着手"=>"not_started", "進行中"=>"in_progress", "完了"=>"done"}
collectionではkeyが表示内容、valueがサーバへ送信される値なので、ハッシュを以下のような形にできれば、ransackで正しく検索できる様になる。
{"未着手"=>0, "進行中"=>1, "完了"=>9}
そのため、collectionに読み込ませる値を以下のようにすると、ransackでも読み取れる値にできる(arrayでもcollectionは問題なく読み込んでくれる模様)
Inquiry.statuses_i18n.invert.map{ |key, value| [key, Inquiry.statuses[value]]}
> [["未着手", 0], ["進行中", 1], ["完了", 9]]
参照:RansackはRailsのenumに対応していないっぽい
https://www.tom08.net/entry/2016/12/05/121746