2015-06-01 50 views
0

我試圖做到這一點傳遞一個運營商紅寶石到SQL在軌道上

Model.where("major :operator :major OR (major = :major AND minor :operator :minor)", :major => major, :minor => minor, :operator => :operator)

這將拋出一個錯誤

ERROR: syntax error at or near "1" LINE 1: ...o_content_view_versions" WHERE (major '=' 1 OR (majo...

這個作品

Model.where("major #{operator} :major OR (major = :major AND minor #{operator} :minor)", :major => major, :minor => minor)

但我擔心sql注入

該運算符作爲字符串傳遞。我怎樣才能做這個查詢,並沒有風險SQL注入。我使用PostgreSQL,導軌3.2,紅寶石1.9

示例值: 操作「<」 大1 次要3

+0

您不能參數化操作符或列名稱。你如何選擇這些運營商?這些用戶是否輸入?如果他們不是用戶輸入,那麼我認爲你不需要擔心SQL注入。確保你的代碼生成正確的操作符並使用它們! – vee

+0

不幸的是,它們是用戶輸入,可以是各種比較運算符。我應該補充說,我使用這個寶石... https://github.com/wvanbergen/scoped_search –

回答

2

如果你知道你支持運營商的列表,你可以通過它之前檢查他們進入SQL。

supported_operators = ['>', '<', '=', '>=','<=','<>','!='] 
raise ArgumentError unless supported_operators.include?(operator) 
Model.where("major #{operator} :major OR (major = :major AND minor #{operator} :minor)", :major => major, :minor => minor) 
+1

優秀的解決方案,雖然'ArgumentError'似乎更適合在這種情況下。我喜歡包含'!='和'<>',即使它們本質上是相同的,它似乎會讓用戶更舒適 – engineersmnky