And*_*rew 0 methods model ruby-on-rails class ruby-on-rails-3
我想知道是否可以做以下事情:
假设我有一个Foo带有数据库属性的Rails模型value.Foobelongs_to Bar,Barhas_many Foos.
在我的模型中,我想做的事情如下:
class Foo < ActiveRecord::Base
belongs_to :bar
def self.average
# return the value of all foos here
end
end
Run Code Online (Sandbox Code Playgroud)
理想情况下,我希望让这个方法返回一个与调用它的范围相匹配的值,这样:
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
Run Code Online (Sandbox Code Playgroud)
可以做这样的事情,如果是这样,怎么办?谢谢!
只要您确保调用方法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
Run Code Online (Sandbox Code Playgroud)
让我们看看当我们创建一些俱乐部和人员时会发生什么:
$ 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
Run Code Online (Sandbox Code Playgroud)