2010-04-21 24 views
3

我试图在该领域,并在查找调用的值都传递:是否有可能对键和值都有可变的查找条件?

@employee = Employee.find(:all, 
       :conditions => [ '? = ?', params[:key], params[:value].to_i) 

输出是

SELECT * FROM `employees` WHERE ('is_manager' = 1) 

这不返回任何结果,但是当我在mysqsl直接试试这个使用相同的调用,而不使用is_manager周围的“',它工作正常。如何将我的PARAMS [:键]值的符号,这样产生的SQL调用如下:

SELECT * FROM `employees` WHERE (is_manager = 1) 

感谢, d

回答

1

您可以使用变量替换来替换列名,而不是使用绑定值:

# make sure the key passed is a valid column 
if Employee.columns_hash[params[:key]] 
    Employee.all :conditions => [ "#{params[:key]} = ?", params[:value]] 
end 

可以进一步保障,确保顺利通过列名的解决方案属于一个预先选定的一组:

if ["first_name", "last_name"].include? [params[:key]] 
    Employee.all :conditions => [ "#{params[:key]} = ?", params[:value]] 
end 
+0

修复了代码中的语法错误。 – 2010-04-21 19:44:48

+0

从安全角度来看,我仍然认为这是一个坏主意。 – konung 2010-04-21 23:32:01

+0

这是一个通用的解决方案。用户可以拥有有效的密钥哈希值并将其用于验证(而不是columns_hash)。他最初的问题是由于使用绑定变量替换列名,导轨将列名用引号括起来。这不会通过为col name参数传递符号(而不是字符串)来解决。我添加了'columns_hash'验证作为添加检查以将列名限制为已知集的指导行。这应该是安全问题。 – 2010-04-22 00:05:21

3

如果你想一个字符串符号转换(这是什么PARAMS [:键]生产,所有你需要做的是

params[:key].to_s.to_sym 

2点:

  1. 一个警告字:符号是 不是垃圾收集。

  2. 确保您的关键不是 号码,如果转换to_s第一 然后to_sym,你的代码将工作,但 你可能会得到一个奇怪的符号像 这样:

    :"5"

+0

感谢尼克。恐怕我也许会问错误的问题。 @employee = Employee.find(:所有, :条件=> [ '=?',则params [:键] .to_s.to_sym,则params [:值] .to_i) 产生下列SQL输出: SELECT * FROM'employees' WHERE('---:is_manager \ n'= 1) 我想我必须在我的逻辑中有一个错误而不是语法。我可以做一个case语句来检查params [:key]是什么,并执行相应的查找(在这种情况下,它将是[:is_manager =?,params [:value] .to_i])。 但我希望能够更有活力一点,不必个别重做每一个案例。 – DarrenD 2010-04-21 16:08:38

+0

我回答了你问的问题,而不是你的意思:-)我不知道你要求什么是可能的或最重要的 - 理想的,至少不是根据rails规范http://api.rubyonrails.org/类/ ActiveRecord/Base.html。问题是这是一个潜在的巨大安全漏洞。假设这是一个人力资源应用程序:如果有人会通过一个关键=薪水。然后他们可以为任何人提供薪水信息或ssn信息。我的意思是,你可以确保你可以提供各种基于角色的安全措施,但是这样做会影响你节省写出你的病例陈述的时间的目的。 – konung 2010-04-21 16:35:14

+0

Gotcha。关键是来自一个选择框,所以我只接受特定的值(加上我认证,因为这是一个'管理'工具)。但我听到你。案例声明是:) – DarrenD 2010-04-21 16:42:09

相关问题