Rails:为需要来自其自己的类成员的信息的类创建方法?

时间:2011-01-19 01:36:10

标签: ruby-on-rails class ruby-on-rails-3 methods model

我想知道是否可以做以下事情:

假设我有一个Rails模型Foo,其数据库属性为valueFoo belongs_to BarBar has_many Foos

在我的模型中,我想做类似的事情:

class Foo < ActiveRecord::Base

  belongs_to :bar

  def self.average
    # return the value of all foos here
  end

end

理想情况下,我希望让此方法返回一个与调用它的范围相匹配的值,以便:

Foo.average # would return the average value of all foos

@bar = Bar.find(1)
@bar.foos.average # would return the average of all foos where bar_id == 1

可以做这样的事情,如果是的话,怎么做?谢谢!

1 个答案:

答案 0 :(得分:5)

只要您确保在self方法的正文中Foo而不是average调用方法,您所拥有的内容将按原样运行。在Foo范围内调用方法时,该方法主体中的self将分配给范围对象而不是Foo。这是一个稍微更具体的例子:

# app/models/club.rb
class Club < ActiveRecord::Base
  # name:string
  has_many :people
end

# app/models/person.rb
class Person < ActiveRecord::Base
  # club_id:integer, name:string, age:integer
  belongs_to :club

  def self.average_age
    # note that sum and count are being called on self, not Person
    sum('age') / count
  end
end

让我们看看当我们创建一些俱乐部和人员时会发生什么:

$ rails console
Loading development environment (Rails 3.0.3)
irb(main):001:0> boys_club = Club.create(:name => 'boys')
irb(main):002:0> girls_club = Club.create(:name => 'girls')
irb(main):003:0> boys_club.people.create(:name => 'bob', :age => 20)
irb(main):004:0> boys_club.people.create(:name => 'joe', :age => 22)
irb(main):005:0> girls_club.people.create(:name => 'betty', :age => 30)
irb(main):006:0> Person.average_age
=> 24
irb(main):007:0> boys_club.people.average_age
=> 21
irb(main):008:0> Person.where("name LIKE 'b%'").average_age
=> 25