2015-07-01 29 views
9

我在编写要在ActiveRecord对象的集合上使用的类方法时遇到问题。在过去的几个小时里,我遇到过两次这样的问题,它看起来像一个简单的问题,所以我知道我错过了一些东西,但我一直无法在其他地方找到答案。用于收集对象的Rails模型类方法

例子:

class Order < ActiveRecord::Base 

    belongs_to :customer 

    scope :month, -> { where('order_date > ?', DateTime.now.beginning_of_month.utc) } 

    def self.first_order_count 
    map(&:first_for_customer?).count(true) 
    end 

    def first_for_customer? 
    self == customer.orders.first 
    # this self == bit seems awkward, but that's a separate question... 
    end 

end 

如果我打电话Order.month.first_order_count,我得到 NoMethodError: undefined method 'map' for #<Class:...

据我所知,这是因为map不能直接在Order调用,但需要一个Enumerable对象,而不是。如果我拨打Order.year.map(&:first_for_customer?).count(true),我会得到理想的结果。

什么是正确的方式来编写方法使用的对象集合,但不是直接在类上?

回答

8

就你而言,你可以在这种情况下使用一个技巧。

def self.first_order_count 
    all.map(&:first_for_customer?).count(true) 
end 

会做的伎俩,没有任何其他的问题,这样一来,如果您连接在where子句你仍然从得到的结果这种方法,其中,这样你会得到,如果你直接在Order调用这个方法,你需要什么。

+0

完美!这个诀窍会让事情变得更容易。我从来没有意识到我可以在一个关系上调用“全部”,而不仅仅是在课堂上。 – elements

+1

你,先生,是天赐之物。我提交了https://github.com/rails/rails/issues/21943,因为这是一个误导性的文档问题,或者最糟糕的一个错误。 – DreadPirateShawn

2

ActiveRecord集合通常使用作用域进行操作,其优点是能够链接它们并让数据库完成繁重的工作。如果你必须在Ruby中管理它,你可以从all开始。

def self.first_order_count 
    all.map(&:first_for_customer?).count(true) 
end 

你想用你的代码实现什么?

+0

我打算只用它链接到另一个范围。感谢您的帮助;我接受另一个答案,因为它是第一个(尽管只是一分钟)。 – elements

相关问题