はじめに
ransackとenum_helpを利用している時、他のenumじゃないカラムと同一の検索ボックスを利用してname_or_job_or_etc_orみたいな検索をしたくなる場合があります。というか、そういう注文がよく飛んできます。
そのまま対応すると、enumな部分だけクエリに%0%とか入ってきて、なんだよこれ、全然だめじゃんよ。ransackってばenumに対応してないじゃんちくしょう。みたいな非常に切ない気分になります。
個別に検索用のセレクトボックスを付けるのも癪であす。bootstrapでシンプルにカッチョ良く決めた画面が、inputの乱立から段々と崩れていくのは悲しいことです。開発を続けるモチベーションも下がってしまいます。
実装
これを解決するのがransackerという、ransackに用意されている切り込み隊長的なオプションです。同オプションを対象のモデルに定義しおくと、上記の問題を簡単に解決することができます。なんて便利なんでしょう。
enum job: { neet: 1, homeless: 2, lolicon: 3 }
ransacker :job, formatter: proc { |v|
sym = User.jobs_i18n.invert[v]
if sym.blank?
-1
else
sym
end
} do |parent|
parent.table[:job]
end
途中で何故か-1を返している部分については、対応するi18nの文字列がconfig/locales/*.ymlに存在しない場合、enumで利用していない値を返すことで対応するためです。もしも-1を利用している場合は、他に絶対使わないだろう値を返すように変更する必要があります。
尚、上記よりこのprocっている部分の実装にミスった場合、予期せぬ越権クエリが走って、想定外のデータまでwhereで引っ張られることになります。あまり複雑なことはしないほうが良いと思いました。