2016-02-25 7 views
9

に参加私は手動joinをやっていると私はそのON句にパラメータを渡す必要があります。パラメータ化はRailsの4

Foo.joins("LEFT OUTER JOIN bars ON foos.id = bars.foo_id AND bars.baz = #{baz}") 

は、潜在的な注入の問題を回避するために、パラメータとしてbazを渡す方法はありますか?メソッドsanitize_sql_arrayがありますが、私はこの場合にどのように使用するかわかりません。

注:それは同じではないので、私はwhereを使用することはできません。

+0

のでバズは、他の参加モデルはありますか?あなたはバズの価値を教えてくれますか? –

+0

うん、それはbazが何であるかも知っていることを知ってうれしい。 – Kulgar

+0

'baz'は文字列リテラルや数値を保持する変数です。これは別のモデルではなく、外部結合のON条件に渡したい値です。 –

答えて

8

、それは次のようになります。

# Warning: sanitize_sql_array is a protected method, be aware of that to properly use it in your code 
ar = ["LEFT OUTER JOIN bars ON foos.id = bars.foo_id AND bars.baz = %s", baz] 
# Within foo model: 
sanitized_sql = sanitize_sql_array(ar) 
Foo.joins(sanitized_sql) 

はそれを試してみました、それが働きました。

+0

@mladenjablanovicを参照してください - それはあなたのために機能しますか? – Kulgar

-2

私はあなたがこのように試してみてくださいと思う:より多くのパラメータを持つ

Foo.joins("LEFT OUTER JOIN bars ON foo.id = bars.foo_id AND bars.baz = ?", baz) 

Foo.joins("LEFT OUTER JOIN bars ON foo.id = ? AND bars.baz = ? AND ...", foo, baz, etc...) 
+1

これは正しいアプローチです。 –

+5

残念ながら、これは動作しません。 'baz'はパラメータ値として解釈されるのではなく、別の結合されたモデルとして解釈されます。あなたはそれを自分で試すことができます。 https://github.com/rails/rails/blob/9b67cb3d394692aa7feb7510aab0871e557d3dd0/activerecord/lib/active_record/relation/query_methods.rb#L1036 –

+0

AFAIK Rails(4.0でも)は、 'JOIN'節のパラメータをサポートしていません。 Mladen氏は結論として、SQL文を生成する必要があります。私はそれを安全に行う方法について[@ Kulgarは正しい]と思う(http://stackoverflow.com/a/35744285/712765)。 –

-2

あなたは値のハッシュを渡す場合、ARは、SQLインジェクションに対してあなたを保護する安全でなければなりません、

Foo.joins("LEFT OUTER JOIN bars ON foo.id = bars.foo_id").where(bars: {baz: baz}) 

sqlのSQLの影響を受けやすい行の文字列を使用しないでください。 sanitize_sql_arrayで

+0

残念ながら、私は欲しいものではありません。 WHEREの条件は、ONの条件と同じではありません。 –

+2

外部結合のために、 'JOIN'節に条件を持つことは、' WHERE'節の条件を持つこととは異なります。 http://sqlfiddle.com/#!9/c827b7/5 –

7

アクティブレコードモデルはsanitizeクラスメソッドを持っているので、あなたが行うことができます:

Foo.joins("LEFT OUTER JOIN bars ON foos.id = bars.foo_id AND bars.baz = #{Foo.sanitize(baz)}") 
関連する問題