pos = Order.find(:all,:conditions => "name = 'dave' and pay_type = 'po'")
find思路方法将返回所有符合条件记录并且都已经被转换成Order类对象如果没有符合条件订单find思路方法将返回个长度为零
如果你条件是预定那么上面写法就很好了但是如果我们要指定条件中值呢我们这样写:
# get the limit amount from the form
name = params[:name]
# DON'T DO THIS!!!
pos = Order.find(:all,:conditions => "name = '#{name}' and pay_type = 'po'")
但是这并不是个好主意如果你要发布在网络上话这样给SQL注入攻击留下了方便(后面我们在有关安全主题里会讨论SQL注入话题)更好办法是动态生成SQL(注1)让Active Record来处理它我们可以在SQL语句中加入占位符然后这些占位符将会在运行期被替换成指定值指定占位符思路方法就是在SQL中使用问号在运行时
第个问号将被替换为集合第 2个元素值以此类推例如我们把上面查询重写次:
name = params[:name]
pos = Order.find(:all,:conditions => ["name = ? and pay_type = 'po'", name])
我们也可以使用带名字占位符名字前带冒号例如下面这样:
name = params[:name]
pay_type = params[:pay_type]
pos = Order.find(:all,
:conditions => ["name = :name and pay_type = :pay_type",
{:pay_type => pay_type, :name => name}])
我也可以更进步params是个hash我们可以让conditions部分更简单
pos = Order.find(:all,
:conditions => ["name = :name and pay_type = :pay_type", params])
不管使用哪种占位符Active Record都会很小心地处理SQL中引号和escape使用动态SQLActive Record会保护我们不受SQL注入攻击
注1:这里动态sql区别于oracle等数据库中所指动态sql其含义类似于ADO.net中不拼接sql串而是传参数来防止sql注入攻击
最新评论