假设我有一个包含3个模型的Rails应用:Job
,Contractor
,Bid
。当承包商针对某个职位出价时,会使用相应的contractor_id
和job_id
创建出价。现在,我想定义一个工作范围,在给定承包商的情况下,返回他们不但尚未出价的工作:
class Job < ActiveRecord::Base
scope :not_bid_on_by, -> (contractor) do
joins(%{
LEFT JOIN bids ON bids.job_id = jobs.id
AND bids.contractor_id = #{ contractor.id }
}).where(bids: { id: nil })
end
end
尽管将值直接内插到joins
字符串中,但我无法想到这个示例容易受到SQL注入的情况,因为它只是内插一个来自给定参数的id
字段。我一般都知道这是一种不好的做法,但这似乎是一个良性的例子。
如果我错了并且 存在安全风险,那么有更安全的方法吗? ActiveRecord似乎没有像joins
那样安全插入where
字符串的方式(?
或命名参数)。
答案 0 :(得分:1)
尝试使用ActiveRecord的sanitize_sql_array
方法:http://api.rubyonrails.org/classes/ActiveRecord/Sanitization/ClassMethods.html#method-i-sanitize_sql_array
示例:
class Job < ActiveRecord::Base
scope :not_bid_on_by, -> (contractor) do
joins( sanitize_sql_array [%{
LEFT JOIN bids ON bids.job_id = jobs.id
AND bids.contractor_id = ?
}, contractor.id]).where(bids: { id: nil })
end
end