ruby-on-rails - update_all 方法

标签 ruby-on-rails ruby ruby-on-rails-4 activerecord rails-activerecord

假设我有一个模型:

class Result < ActiveRecord::Base
  attr_accessible :x, :y, :sum
end

而不是做

Result.all.find_each do |s|
  s.sum = compute_sum(s.x, s.y)
  s.save
end

假设 compute_sum 是一种可用的方法,并进行一些无法转换为 SQL 的计算。

def compute_sum(x,y)
  sum_table[x][y]
end

有没有办法使用update_all,大概是这样的:

Result.all.update_all(sum: compute_sum(:x, :y))

我有超过 80,000 条记录要更新。 find_each 中的每条记录都创建自己的BEGINCOMMIT 查询,并且每条记录都单独更新。

或者还有其他更快的方法吗?

最佳答案

如果无法将 compute_sum 函数转换为 sql,则无法一次对所有记录执行 update_all。您将需要迭代各个实例。但是,如果列中有很多重复的值集,您可以加快速度,方法是每组输入只计算一次,然后每次计算进行一次质量更新。例如

Result.all.group_by{|result| [result.x, result.y]}.each do |inputs, results|
  sum = compute_sum(*inputs)
  Result.update_all('sum = #{sum}', "id in (#{results.map(&:id).join(',')})")
end

您可以将 result.x、result.y 替换为 compute_sum 函数的实际输入。

编辑 - 忘记在 group_by block 中将 result.x、result.y 放在方括号中。

关于ruby-on-rails - update_all 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33231610/

相关文章:

ruby-on-rails - 为什么 rails 在设置后更改属性 _was 值的类型?

ruby-on-rails - Rails 4.2.0 中简单整数赋值的 RangeError 应该被验证捕获

ruby - 算法 - 这个埃拉托色尼筛法解决方案有什么问题

ruby-on-rails - Rails 4 - 更新多个表条目

angularjs - Rails 在发生变化时触发特定 Assets 的重建

ruby-on-rails - 添加用户名以设计 rails 4

ruby-on-rails - 运行配置文件测试时出现 Ruby 段错误

ruby - 我应该学习 Ruby 1.8 还是 1.9?

arrays - 在一行中选择数组的第一个和最后一个元素

Mysql2::错误: 'comments' 中的未知列 'having clause'