我必须清理 sql 查询的一部分。我可以做这样的事情:
class << ActiveRecord::Base
public :sanitize_sql
end
str = ActiveRecord::Base.sanitize_sql(["AND column1 = ?", "two's"], '')
但这并不安全,因为我公开了受保护的方法。有什么更好的方法呢?
我必须清理 sql 查询的一部分。我可以做这样的事情:
class << ActiveRecord::Base
public :sanitize_sql
end
str = ActiveRecord::Base.sanitize_sql(["AND column1 = ?", "two's"], '')
但这并不安全,因为我公开了受保护的方法。有什么更好的方法呢?
You can just use:
ActiveRecord::Base::sanitize_sql(string)
ActiveRecord::Base.connection.quote
在 Rails 3.x 中解决问题
这个问题没有指定答案必须来自,ActiveRecord
也没有指定它应该是哪个版本的 Rails。出于这个原因(并且因为它是顶级和少数几个)关于如何清理 Rails 中的参数的答案......
这是一个适用于 Rails 4 的解决方案:
在ActiveRecord::Sanitization::ClassMethods
你有sanitize_sql_for_conditions和它的另外两个别名:
sanitize_conditions和sanitize_sql。这三个人实际上做的是完全相同的事情。
sanitize_sql_for_conditions
接受一个数组、散列或 SQL 条件字符串,并将它们清理为 WHERE 子句的有效 SQL 片段。
同样在 ActiveRecord 你有
sanitize_sql_for_assignment
哪个
接受一个数组、散列或 SQL 条件字符串,并将它们清理为 SET 子句的有效 SQL 片段。
查看文档
但是,另外,在 ActionController 你有ActionController::Parameters
它允许你
选择应将哪些属性列入白名单以进行大规模更新,从而防止意外暴露不应暴露的属性。为此提供了两种方法:require和permit。
params = ActionController::Parameters.new(user: { name: 'Bryan', age: 21 })
req = params.require(:user) # will throw exception if user not present
opt = params.permit(:name) # name parameter is optional, returns nil if not present
user = params.require(:user).permit(:name, :age) # user hash is required while `name` and `age` keys are optional
“参数魔法”被称为强参数(此处的文档),您可以使用它来清理控制器中的参数,然后再将其发送到模型。
ActionController::Base
,因此也包含在其中。我希望这对任何人都有帮助,即使只是为了学习和揭开 Rails 的神秘面纱!:)
从 rails 5 开始,推荐的方法是使用:ActiveRecord::Base.connection.quote(string)
如此处所述:https ://github.com/rails/rails/issues/28947
ActiveRecord::Base::sanitize(string)
已弃用
请注意,在清理 SQL WHERE 条件时,最好的解决方案是 sanitize_sql_hash_for_conditions,因为它正确处理了 NULL 条件(例如,如果传递了 nil 属性,则会生成IS NULL
而不是生成)。= NULL
由于某种原因,它在 Rails 5 中已被弃用。所以我推出了一个面向未来的版本,请参见此处:https ://stackoverflow.com/a/53948665/165673