2012-10-31 33 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是否存在。