简体   繁体   English

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

[英]sum() or group() virtual attributes in ruby on rails

let's say I have a model like this: 假设我有一个这样的模型:

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

  def area
     self.width * self.length
  end
end

Where @surface.area returns the area of a surface. 其中@surface.area返回曲面的面积。 Now, lets say I have many surfaces called @surfaces and I want to sum all areas. 现在,假设我有许多名为@surfaces表面,我想总结所有区域。 How do I do this? 我该怎么做呢?

My favorite solution would look like this: 我最喜欢的解决方案如下:

@surfaces.sum(:area)

But it does not work. 但它不起作用。 So how can I call .sum() or .group() or any similar functions on a virtual attributes like this in rails? 所以,我怎么能叫.sum().group()或在轨虚拟属性,任何像这样类似的功能? I would like to avoid .each do |surface| 我想避免.each do |surface| calls. 调用。

Thanks in advance. 提前致谢。

sum will quite happily accept an SQL expression instead of just a column name so all you need to do is translate your sum method into SQL: sum非常乐意接受一个SQL表达式而不仅仅是一个列名,所以你需要做的就是将sum方法转换为SQL:

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

Also, class methods on your models are mixed into relations (since scopes and class methods are really the same thing) so you could add a class method to go with your instance method: 此外,模型中的类方法被混合到关系中(因为范围和类方法实际上是相同的),因此您可以添加一个类方法来与您的实例方法一起使用:

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

and say: 并说:

@surfaces.area

You're usually better off letting the database do the heavy lifting with your data, that's what they're for and what they're good at. 通常情况下,让数据库对您的数据进行繁重的处理会更好,这就是他们的目标以及他们擅长的目标。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM