43

我必须清理 sql 查询的一部分。我可以做这样的事情:

class << ActiveRecord::Base
  public :sanitize_sql
end

str = ActiveRecord::Base.sanitize_sql(["AND column1 = ?", "two's"], '')

但这并不安全,因为我公开了受保护的方法。有什么更好的方法呢?

4

5 回答 5

53

You can just use:

ActiveRecord::Base::sanitize_sql(string)
于 2012-06-28T15:27:16.547 回答
16

ActiveRecord::Base.connection.quote在 Rails 3.x 中解决问题

于 2012-02-27T14:44:52.280 回答
14

这个问题没有指定答案必须来自,ActiveRecord也没有指定它应该是哪个版本的 Rails。出于这个原因(并且因为它是顶级和少数几个)关于如何清理 Rails 中的参数的答案......


这是一个适用于 Rails 4 的解决方案:

ActiveRecord::Sanitization::ClassMethods你有sanitize_sql_for_conditions和它的另外两个别名:   sanitize_conditionssanitize_sql。这三个人实际上做的是完全相同的事情。

sanitize_sql_for_conditions

接受一个数组、散列或 SQL 条件字符串,并将它们清理为 WHERE 子句的有效 SQL 片段。

同样在 ActiveRecord 你有

sanitize_sql_for_assignment哪个

接受一个数组、散列或 SQL 条件字符串,并将它们清理为 SET 子句的有效 SQL 片段。

  • 上述方法默认包含在 ActiveRecord::Base 中,因此包含在任何 ActiveRecord 模型中。

查看文档


但是,另外,在 ActionController 你有ActionController::Parameters它允许你

选择应将哪些属性列入白名单以进行大规模更新,从而防止意外暴露不应暴露的属性。为此提供了两种方法:requirepermit

   

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

“参数魔法”被称为强参数(此处的文档),您可以使用它来清理控制器中的参数,然后再将其发送到模型。

  • 上述方法默认包含在任何 Rails 控制器中ActionController::Base因此也包含在其中

我希望这对任何人都有帮助,即使只是为了学习和揭开 Rails 的神秘面纱!:)

于 2016-02-24T16:56:32.610 回答
9

从 rails 5 开始,推荐的方法是使用:ActiveRecord::Base.connection.quote(string)

如此处所述:https ://github.com/rails/rails/issues/28947

ActiveRecord::Base::sanitize(string)已弃用

于 2018-07-11T09:22:11.790 回答
1

请注意,在清理 SQL WHERE 条件时,最好的解决方案 sanitize_sql_hash_for_conditions,因为它正确处理了 NULL 条件(例如,如果传递了 nil 属性,则会生成IS NULL而不是生成)。= NULL

由于某种原因,它在 Rails 5 中已被弃用。所以我推出了一个面向未来的版本,请参见此处:https ://stackoverflow.com/a/53948665/165673

于 2018-12-27T17:38:18.087 回答