rails ruby 中的 sum() 或 group() 虚拟属性

sum() or group() virtual attributes in ruby on rails

假设我有这样一个模型:

class Surface < ActiveRecord::Base
  attr_accessible :width, :length

  def area
     self.width * self.length
  end
end

其中 @surface.area returns 表面的面积。现在,假设我有许多名为 @surfaces 的表面,我想对所有区域求和。我该怎么做?

我最喜欢的解决方案如下所示:

@surfaces.sum(:area)

但是没有用。那么如何在 rails 中调用 .sum().group() 或任何类似的虚拟属性函数?我想避免 .each do |surface| 电话。

提前致谢。

可以通过Enumerable#reduce方法实现:

@surfaces.reduce(0){ |sum, surface| sum + surface.area }

sum 会很乐意接受 SQL 表达式,而不仅仅是列名,因此您需要做的就是将 sum 方法转换为 SQL:

@surfaces.sum('width * height')
@surfaces.sum('surface.width * surface.height') # If you think other tables might be involved.

此外,模型中的 class 方法混合到关系中(因为作用域和 class 方法实际上是同一件事)因此您可以添加一个 class 方法来配合你的实例方法:

class Surface < ActiveRecord::Base
  def self.area
    sum('surface.width * surface.height')
  end
  def area
     self.width * self.length
  end
end

然后说:

@surfaces.area

通常最好让数据库来处理您的数据,这就是它们的用途和擅长之处。