То, что у вас есть, будет работать, как есть, до тех пор, пока вы будете вызывать методы на 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