1

私は検索可能なモデルの属性を表す属性の束を持つオブジェクトを持って、私は動的に設定されている属性のみを使用してSQLクエリを作成したいと思います。以下の方法を作成しましたが、SQLインジェクション攻撃の影響を受けやすいと思います。私はいくつかの調査を行い、レール上のアクティブレコードクエリーインターフェイスガイドを読んでいましたが、where条件は常に静的に定義された文字列を最初のパラメータとして必要とするようです。私はまた、私のメソッドで生成されたSQL文字列をサニタイズする方法を見つけようとしましたが、それを行うには良い方法があるようには思えません。rails dynamicここではsqlクエリ

どうすればよいですか?私はどこの条件を使用するか、ちょうど何とかこのSQL文字列をサニタイズする必要がありますか?ありがとう。

def query_string 
    to_return = "" 

    self.instance_values.symbolize_keys.each do |attr_name, attr_value| 
    if defined?(attr_value) and !attr_value.blank? 
     to_return << "#{attr_name} LIKE '%#{attr_value}%' and " 
    end 
    end 
    to_return.chomp(" and ") 
end 

答えて

1

間違った問題を解決しようとしているので、あなたのアプローチは少しです。 ActiveRecordに渡す文字列を作成しようとしているので、単にクエリを作成しようとしているときにクエリを構築できます。

あなたが何か言う:言うのと同じです

Model.where('a and b') 

Model.where('a').where('b') 

を、あなたが言うことができます。

Model.where('c like ?', pattern) 

の代わり:

Model.where("c like '#{pattern}'") 

def query 
    self.instance_values.select { |_, v| v.present? }.inject(YourModel) do |q, (name, value)| 
    q.where("#{name} like ?", "%#{value}%") 
    end 
end 

かさえ:あなたのself.instance_valuesあなたのような何かを得ることができて、これらの2つのアイデアを組み合わせる

def query 
    empties  = ->(_, v) { v.blank? } 
    add_to_query = ->(q, (n, v)) { q.where("#{n} like ?", "%#{v}%") } 
    instance_values.reject(&empties) 
       .inject(YourModel, &add_to_query) 
end 

それらはすべてのあなたのインスタンス変数を適切にホワイトリストに登録したことを前提としています。あなたはしていない場合は、する必要があります。

+0

うわー、私はあなたのRubyのスキルに驚いています。 2番目の例は、心臓発破です。ありがとう! –

関連する問題