Rails,如何在find_by_sql中清理SQL

not*_*ere 16 activerecord ruby-on-rails find-by-sql ruby-on-rails-3

有没有办法在rails方法中清理sql find_by_sql

我尝试过这个解决方案: Ruby on Rails:如何在不使用find时清理SQL的字符串?

但它失败了

Model.execute_sql("Update users set active = 0 where id = 2")
Run Code Online (Sandbox Code Playgroud)

它会抛出一个错误,但执行了sql代码,ID为2的用户现在已经禁用了帐户.

简单find_by_sql也行不通:

Model.find_by_sql("UPDATE user set active = 0 where id = 1")
# => code executed, user with id 1 have now ban
Run Code Online (Sandbox Code Playgroud)

编辑:

好吧,我的客户端要求在管理面板中创建该功能(由sql选择)以进行一些复杂的查询(连接,特殊条件等).所以我真的想find_by_sql那个.

第二编辑:

我想实现'邪恶的'SQL代码不会被执行.

在管理面板中,您可以键入query - > Update users set admin = true where id = 232,我想阻止任何UPDATE/DROP/ALTER SQL命令.只是想知道,在这里你只能执行SELECT.

经过一些尝试后,我总结说sanitize_sql_array不幸的是不这样做.

有没有办法在Rails中做到这一点?

对困惑感到抱歉..

bor*_*r1s 13

试试这个:

connect = ActiveRecord::Base.connection();
connect.execute(ActiveRecord::Base.send(:sanitize_sql_array, "your string"))
Run Code Online (Sandbox Code Playgroud)

您可以将其保存在变量中并用于您的目的.

  • 最后一个工作...但它仍然执行'邪恶的'SQL代码.;) (2认同)

Mic*_*per 10

我为此做了一个小片段,你可以放入初始化器.

class ActiveRecord::Base  
  def self.escape_sql(array)
    self.send(:sanitize_sql_array, array)
  end
end
Run Code Online (Sandbox Code Playgroud)

现在,您可以使用以下命令来转义查询:

query = User.escape_sql(["Update users set active = ? where id = ?", true, params[:id]])
Run Code Online (Sandbox Code Playgroud)

您可以按照自己喜欢的方式调用查询:

users = User.find_by_sql(query)
Run Code Online (Sandbox Code Playgroud)

  • 这个工作,但只是抬头,你不需要"发送".当调用者是同一个类时,接收者允许调用受保护的方法.也就是说,你只需要方法定义:"def self.escape_sql(obj); sanitize_sql_array obj; end;" (自SO注释以来使用的分号允许返回行) (2认同)

Jay*_*itt 8

稍微多一般用途:

class ActiveRecord::Base  
  def self.escape_sql(clause, *rest)
    self.send(:sanitize_sql_array, rest.empty? ? clause : ([clause] + rest))
  end
end
Run Code Online (Sandbox Code Playgroud)

这个让你调用它就像你输入where子句,没有额外的括号,并使用数组样式?或散列样式插值.


c g*_*c g 6

User.find_by_sql(["SELECT * FROM users WHERE (name = ?)", params])
Run Code Online (Sandbox Code Playgroud)

资料来源:http//blog.endpoint.com/2012/10/dont-sleep-on-rails-3-sql-injection.html

  • 通常最好包括对您提供的代码的解释,而不是简单地链接到解释它的博客。如果该博客的所有者更新帖子以不再包含您提供的代码、删除帖子或删除博客,会发生什么情况? (2认同)