简体   繁体   中英

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. Now, lets say I have many surfaces called @surfaces and I want to sum all areas. 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? I would like to avoid .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:

@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 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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