2012-10-31 66 views
0

我想在特定列表中查找所有帶有共同名稱或內部名稱的小部件query_list。我可以做通過查找,sql或其他方式安全查詢

# Consider query_list = ["a","b","c"] 
qlist = '(' + query_list.join(",") + ')' 
# this makes 
widgets = Widget.find_by_sql("SELECT * FROM widgets 
    WHERE common_name IN #{qlist} OR internal_name IN #{qlist}") 

現在我有幾個問題:

  1. 就是上面的find_by_sql安全有關SQL注入攻擊?看起來好像可以在query_list中發生危險的事情。
    • 寫作如何.find_by_sql(["SELECT * FROM widgets WHERE common_name IN ? OR internal_name IN ?", ["a","b","c"], ["a","b","c"] ])
    • 如果不安全,我們可以安全嗎?
  2. 如果我不需要,我寧願不寫原始的sql。我知道我們可以在find中編寫AND條件,如.find(:conditions=>{:internal_name => ['a','b','c'], :common_name => ['a','b','c']})。我們是否也可以使用find編寫OR條件?
  3. 如何使用where?這與使用find有什麼不同?

回答

0

只要您不介意用戶可以選擇任意小部件,我認爲您不需要,帶佔位符的版本可以安全地防止SQL注入。根據您擁有的Rails版本,您可以避免使用鏈接編寫原始SQL;見Ruby on Rails 3 howto make 'OR' condition

請注意,如果列表爲空,或者是[nil],那麼代碼原樣或使用佔位符將導致數據庫錯誤,因此最好在進行查詢之前測試query_list.first是否存在。