Rails,如何在find_by_sql中清理SQL

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

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

但它失败了

 Model.execute_sql("Update users set active = 0 where id = 2") 

它会抛出一个错误,但执行了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 

编辑:

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

第二编辑:

我想实现’邪恶的’SQL代码不会被执行。

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

经过一些尝试,我得出结论sanitize_sql_array不幸的是不要这样做。

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

对困惑感到抱歉..

试试这个:

 connect = ActiveRecord::Base.connection(); connect.execute(ActiveRecord::Base.send(:sanitize_sql_array, "your string")) 

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

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

 class ActiveRecord::Base def self.escape_sql(array) self.send(:sanitize_sql_array, array) end end 

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

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

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

 users = User.find_by_sql(query) 

略多一般用途:

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

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

User.find_by_sql([“SELECT * FROM users WHERE(name =?)”,params])发现于http://blog.endpoint.com/2012/10/dont-sleep-on-rails-3-sql-injection html的

虽然此示例适用于INSERT查询,但可以使用类似的方法进行UPDATE查询。 原始SQL批量插入:

 users_places = [] users_values = [] timestamp = Time.now.strftime('%Y-%m-%d %H:%M:%S') params[:users].each do |user| users_places << "(?,?,?,?)" # Append to array users_values << user[:name] << user[:punch_line] << timestamp << timestamp end bulk_insert_users_sql_arr = ["INSERT INTO users (name, punch_line, created_at, updated_at) VALUES #{users_places.join(", ")}"] + users_values begin sql = ActiveRecord::Base.send(:sanitize_sql_array, bulk_insert_users_sql_arr) ActiveRecord::Base.connection.execute(sql) rescue "something went wrong with the bulk insert sql query" end 

以下是对ActiveRecord :: Base中的sanitize_sql_array方法的引用 ,它通过转义字符串中的单引号来生成正确的查询字符串。 例如,punch_line“不要让他们让你失望”将成为“不要让他们让你失望”。