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

发布于 2024-10-12 16:11:06 字数 601 浏览 2 评论 0原文

我想知道是否可以执行如下操作:

假设我有一个 Rails 模型 Foo,带有数据库属性 valueFoo 属于 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

这样的事情可以完成吗?如果可以,如何完成?谢谢!

I was wondering if it's possible to do something like follows:

Let's say I have a Rails model, Foo, with a database attribute value. Foo belongs_to Bar, Bar has_many Foos.

In my model, I'd like to do something like:

class Foo < ActiveRecord::Base

  belongs_to :bar

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

end

Ideally I'd like to have this method return a value that matched the scope from which it was called, so that:

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

Can such a thing be done, and if so, how? Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

遇见了你 2024-10-19 16:11:06

只要您确保在 average 方法主体中调用 self 上的方法而不是 Foo 上的方法,您所拥有的就可以按原样工作。当调用 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

What you have will work as is, as long as you make sure to call methods on self instead of Foo in the body of the average method. When calling methods on a scope of Foo, self in the body of that method will be assigned to the scope object rather than Foo. Here's a slightly more concrete example:

# 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

Let's see what happens when we create some clubs and people:

$ 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文