Rails - 如何正确转义update_all查询中的值

时间:2015-02-19 11:00:54

标签: sql ruby-on-rails escaping sql-injection

所以我有一个update_all查询,如下所示:

Task.where(...).update_all('position = position - X, parent_id = Y')

我想用整数值替换X和Y.而且我想安全地做到:“铁路方式”。 知道如何实现这个目标吗?


编辑:我的rails控制器中没有位置变量。如果X = 1,则最终查询应该包含“position = position-1”。

此外,update_all documentation指定此方法只接受一个参数:表示SQL语句的SET部分的字符串,数组或散列。


编辑2:好吧,我通过略微调整Arup Rakshit解决方案来实现它。这是最终的工作解决方案:

Task.update_all(['position = position - ?, parent_id = ?', X, Y])

2 个答案:

答案 0 :(得分:8)

写为:

Task.where(...)
    .update_all(['position = ?, parent_id = ?', position - X, Y])

阅读update_all

  

条件 - 一个SQL片段,例如“administrator = 1”或[“user_name =?”,用户名]。有关详细信息,请参阅介绍中的条件。

<强>演示:

Loading development environment (Rails 4.2.0)
[1] pry(main)> Person.pluck(:name, :email)
   (0.4ms)  SELECT "people"."name", "people"."email" FROM "people"
=> [["xxxx", nil], ["xxxx", nil], ["xxxx", nil]]
[3] pry(main)> Person.where(email: nil).update_all ["name = ?, email = ?", "foo", "test@test.com"]
  SQL (0.7ms)  UPDATE "people" SET name = 'foo', email = 'test@test.com' WHERE "people"."email" IS NULL
=> 3
[4] pry(main)> Person.pluck(:name, :email)
   (0.3ms)  SELECT "people"."name", "people"."email" FROM "people"
=> [["foo", "test@test.com"], ["foo", "test@test.com"], ["foo", "test@test.com"]]
[5] pry(main)>

答案 1 :(得分:0)

尝试这样做:

Task.where(...).update_all("position = ?, parent_id = ?",position - X, Y )