@jnchito さんに教えてもらったRansackという検索機能を簡単に作ることができるgemを調べてみました。
Readmeをがんばって読んでみます。
名前の意味
まずは「ransack」を辞書で引いてみました。
【動詞】 【他動詞】
1 〔…を求めて〕〈場所を〉くまなく探る[探す], あさり回る 〔for〕.
〈…するために〉〈場所を〉くまなく探す 〈to do〉.
2 〈場所から〉ものを奪う.
要約すると「めちゃくちゃ探し回る」という意味のようです。「find」や「search」よりもねちっこい感じでしょうか。検索に特化したライブラリということがうかがえます。
クエリ文字列が長くなるのでPOSTメソッドを使おう
ransackは検索機能を強力なものにしてくれますが、クエリ文字列が長くなってしまうのが玉にキズです。RESTfulじゃなくなってしまうので甚だ遺憾ではありますがPOSTメソッドでリクエストしましょう。
searchの代わりにransackを使おう
Modelに追加されるsearch
メソッドは、「他のgemと名前がぶつかるので困る」という声が寄せられたようで、代わりにransack
メソッドを使おう。ということが書かれていました。次のメジャーバージョン(2.0)ではsearch
は非推奨になるかも知れません。
ransacker
ransacker
メソッドを使うと、Arelを使った独自の検索機能を追加することができます。
(よくわからなかったのであとで調べる)
検索できる項目の制限
ransackはフォームを自動生成してくれたりしてとても便利なのですが、偽装されたリクエストパラメータを元にして、見られたくない項目で検索されてしまう可能性があります。検索対象のテーブルだけでなく、関連するテーブルも同様です。
ransackのデフォルトでは全ての項目、全ての関連テーブルを許可していますが、検索を許可する項目や関連テーブルを制限するための方法が提供されています。
モデルクラスに追加される以下の4つのメソッドをオーバーライドすることで、項目に制限をかけることができます。
# 検索できる項目名。デフォルトでは全ての項目。
#
def ransackable_attributes(auth_object = nil)
column_names + _ransackers.keys
end
# 参照できる関連テーブル。デフォルトは関連付く全てのテーブル
#
def ransackable_associations(auth_object = nil)
reflect_on_all_associations.map { |a| a.name.to_s }
end
# ソート可能な項目。デフォルトは検索できる項目名と同じ
#
def ransortable_attributes(auth_object = nil)
ransackable_attributes(auth_object)
end
# ransackが使用できるスコープ?
# デフォルトは空。
def ransackable_scopes(auth_object = nil)
[]
end
気になったこと
検索できる項目の制限については、個人情報を抜かれるとかそういった類のものではないと思いますが、ユーザーに提供していない検索条件でデータの絞り込みを行われることで、意図しないリスクがあるのかもしれません。
どのような危険があるのかはおもいつきませんが、利用できる検索条件は絞っておいたほうがいいような気がしました。