如果无法使用ActiveRecord高效表达查询,那么在插入传递ActiveRecord::Base.connection.execute
属性时如何安全地使用params
?
connection.execute "... #{params[:search]} ..."
答案 0 :(得分:11)
您可以使用ActiveRecord::Sanitization::ClassMethods中的方法。
您必须要小心谨慎,因为它们受到保护,因此只能用于ActiveRecord::Base
子类。
在模型类中,您可以执行以下操作:
class MyModel < ActiveRecord::Base
def bespoke_query(params)
query = sanitize_sql(['select * from somewhere where a = ?', params[:search]])
connection.execute(query)
end
end
您也可以send
方法在控制台上试用它:
> MyModel.send(:sanitize_sql, ["Evening Officer ?", "'Dibble'"])
=> "Evening Officer '\\'Dibble\\''"
答案 1 :(得分:2)
ActiveRecord有一个清理方法,允许您先清理查询。 也许你可以研究一下:http://apidock.com/rails/v4.1.8/ActiveRecord/Sanitization/ClassMethods/sanitize
我要非常小心地直接插入参数。 你遇到什么问题,你不能使用ActiveRecord?
答案 2 :(得分:0)
您可以使用ActiveRecord::Base
中的函数来清理SQL查询。例如。 sanitize_sql_array
。如其他答案中所述,它们受到保护,但无需处理继承就可以解决。
sanitize_sql_array
接受一个字符串数组,其中第一个元素是查询,随后的元素将替换查询中的?
个字符。
query = 'SELECT * FROM users WHERE id = ? OR first_name = ?'
id = 1
name = 'Alice'
sanitized_query = ActiveRecord::Base.send(:sanitize_sql_array, [query, id, name])
response = ActiveRecord::Base.connection.execute(sanitized_query)