Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails根据其字段值更新多个记录_Ruby On Rails_Ruby_Activerecord_Orm_Arel - Fatal编程技术网

Ruby on rails Rails根据其字段值更新多个记录

Ruby on rails Rails根据其字段值更新多个记录,ruby-on-rails,ruby,activerecord,orm,arel,Ruby On Rails,Ruby,Activerecord,Orm,Arel,我有一个Subscription模型,其中有一个price字段,我的上一次迁移引入了一个名为peru\u month\u price的字段。我正在寻找一种比简单的.each{…}更新记录更快的方法。例如: Subscription.update_all{| c | c.peru_\u month_price=c.price/12}也许我遗漏了一些东西,但如果可以通过编程从现有列中确定,为什么还要将其添加到数据库中呢?只需创建一个虚拟属性: class Subscription < Acti

我有一个
Subscription
模型,其中有一个
price
字段,我的上一次迁移引入了一个名为
peru\u month\u price
的字段。我正在寻找一种比简单的
.each{…}
更新记录更快的方法。例如:


Subscription.update_all{| c | c.peru_\u month_price=c.price/12}

也许我遗漏了一些东西,但如果可以通过编程从现有列中确定,为什么还要将其添加到数据库中呢?只需创建一个虚拟属性:

class Subscription < ActiveRecord::Base

  .
  .
  .

  def per_month_price
    self.price / 12
  end

  def per_month_price=(arg)
    self.price = arg*12
  end

end
类订阅
这将与数据库中的“每月价格”列的功能相同。它将更加高效,因为您不必如此频繁地访问数据库,并且它消除了(很可能)以下情况的可能性:
price
peru_\u month\u price
列在某个地方彼此不一致,例如,如果您更新了一个,但忘记了更新另一个


很抱歉,我没有直接回答您的问题(特别是对通过谷歌来到这里的任何人),但对我来说,这似乎是一个更好的设计。

您可以尝试使用原始sql来完成。我不确定语法是否是标准的SQL,它可能不适用于所有的DBs

ActiveRecord::Base.connection.execute('UPDATE Subscription SET per_month_price = price / 12')
这似乎可以

为什么不简单地使用

Subscription.update_all( "per_month_price = price / 12" )
这是有效的。它接受语句并运行所有找到的记录。 这在rails中非常常见


投票前请检查

糟糕的是,我撤回了我的投票@MarekLipka感谢您指出这一点。您可以将其包装在一个事务中,以节省预处理和后处理(创建索引等)的一些周期。但是,我确实认为性能在这里不应该太重要,因为它只运行一次代码。如中所述。不需要从外部获取参数。因此,它运行sql语句将price/12填充到peru_month_price中。