我必须清理sql查询的一部分。我可以这样做:
class << ActiveRecord::Base
public :sanitize_sql
end
str = ActiveRecord::Base.sanitize_sql(["AND column1 = ?", "two's"], '')
但它不安全,因为我公开了受保护的方法。有什么更好的方法呢?
答案 0 :(得分:42)
你可以使用:
ActiveRecord::Base::sanitize(string)
答案 1 :(得分:14)
ActiveRecord::Base.connection.quote
在Rails 3.x
答案 2 :(得分:8)
这个问题没有说明答案必须来自ActiveRecord
,也没有说明它应该是哪个版本的Rails。出于这个原因(并且因为它是最重要的和少数几个)关于如何在Rails中清理参数的答案......
这是一个适用于Rails 4的解决方案:
在ActiveRecord::Sanitization::ClassMethods
中您有 sanitize_sql_for_conditions 及其他两个别名:
sanitize_conditions 和 sanitize_sql 。这三者确实完全相同。
sanitize_sql_for_conditions
接受SQL条件的数组,散列或字符串并进行清理 它们是一个有效的SQL片段,用于WHERE子句。
同样在ActiveRecord中你有
sanitize_sql_for_assignment
接受SQL条件的数组,散列或字符串并对其进行清理 到一个有效的SQL片段用于SET子句。
请参阅docs
但是,在ActionController中,您有ActionController::Parameters
,允许您
选择哪些属性应列入白名单以进行批量更新 从而防止意外暴露不应暴露的东西。 为此提供了两种方法:需要和允许。
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
“参数魔术”称为强参数(docs here),您可以使用它来清理控制器中的参数,然后再将其发送到模型。
ActionController::Base
中,因此包含在任何Rails控制器中。我希望能帮助任何人,如果只是为了学习和揭开Rails的神秘面纱! :)
答案 3 :(得分:4)
您可以通过间接调用来绕过方法的protected
:
str = ActiveRecord::Base.__send__(:sanitize_sql, ["AND column1 = ?", "two's"], '')
...至少可以让你不得不将该方法改为public
。
(我有点怀疑你确实需要这样做,但上面的方法会有效。)
答案 4 :(得分:3)
从滑轨5开始,推荐的方式是使用:ActiveRecord::Base.connection.quote(string)
如此处所述:https://docs.scipy.org/doc/numpy/user/basics.rec.html
ActiveRecord::Base::sanitize(string)
已弃用
答案 5 :(得分:0)
请注意,在清理SQL WHERE条件时,最好的解决方案是 sanitize_sql_hash_for_conditions,因为它可以正确处理NULL条件(例如,将生成IS NULL
而不是{{ 1}}(如果已传递nil属性)。
由于某种原因,它在Rails 5中已弃用。因此,我推出了一个面向未来的版本,请参见:https://stackoverflow.com/a/53948665/165673