6

私はusername、last_name、first_nameのいずれかの文字列をチェックする簡単な検索機能を実装しています。私は古いRailsCastでこのActiveRecordの方法を見てきました:それは名前、LAST_NAMEと最初の名前のキーワードを検索し、もしレコードを返すようにRails ActiveRecord - 複数の属性で検索

http://railscasts.com/episodes/37-simple-search-form

find(:all, :conditions => ['name LIKE ?', "%#{search}%"]) 

しかし、私はそれをどのように作るのですかフィールドの1つが用語と一致しましたか?

RailsCastのコードにSQLインジェクションが発生する可能性があるのでしょうか?

ありがとうございます!

答えて

20

私はあなたのモデル名がモデルであると仮定 - あなたが実際のクエリ実行するときだけあなたの本当のモデル名に置き換える:SQLインジェクションについてのお悩みについて

Model.where("name LIKE ? OR last_name LIKE ? OR first_name LIKE ?", "%#{search}%","%#{search}%","%#{search}%") 

を - コードスニペットの両方がSQLインジェクションに対して免疫があります。文字列をWHERE節に直接埋め込まない限り、あなたは大丈夫です。注入しやすいコードの例は次のようになります。

Model.where("name LIKE '#{params[:name]}'") 
+0

ちょうど私が必要としたもの。それを明確に説明してくれてありがとう! – maru

+0

'params [:search]'ではなく 'params'全体を渡すようにコントローラを変更した場合、クエリでは'%#{param [:search]}% {search}% "'それでもSQLインジェクションの影響を受けませんか? – Dennis

+0

@Dennisはいそうです。あなたが使っている限り?あなたは問題ありません。 –

8

選択答えは動作しますがラウルので、私は、あなたが検索「ラウルリエラ」と入力しようとした場合、それは両方のケースでは失敗しますので、それが壊れることに気づきましたリエラは、いずれかの私の最初の名前や私の最後の名前ではありません...私の最初と最後の名前である...私はこれを行うには

Model.where("lower(first_name || ' ' || last_name) LIKE ?", "%#{search.downcase}%") 
+0

このような名前を付けるほうが便利です。ありがとう! –

+0

ダウンキーではなくILIKEを使用するほうがよいでしょうか? DBはそれを処理させます。 –

+0

last_nameまたはfirst_nameがnilに等しい場合は機能しません。そうであれば、デフォルトの空の文字列値を姓と名に設定する必要があります –

0

最良の方法を実行して、それを解決するには、次のとおりです。

Model.where("attr_a ILIKE :query OR attr_b ILIKE :query", query: "%#{query}%") 
0

付きArel、あなたは書くことを避けることができます

Model.where(
    %i(name first_name last_name) 
    .map { |field| Model.arel_table[field].matches("%#{query}%") 
    .inject(:or) 
) 

これは、一致するフィールドのリストが動的だった場合に特に便利です。

関連する問題