2015-07-01 71 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

相關問題