2012-10-12 34 views
0

在樣品的Rails 3.2.8應用(上紅寶石1.9.3)有以下簡單設置:導軌3收集`sum`失敗,類型錯誤

class Account < ActiveRecord::Base 
    has_many :line_items 

    def subtotal 
    line_items.sum(&:price) 
    end 
end 

class Line_Item < ActiveRecord::Base 
    belongs_to :product 

    def price 
    product.price * time 
    end 
end 


account = Account.new 

account.line_items.build do |item| 
    item.years = 4 
    item.product = Product.last 
end 

account.subtotal 
#=> TypeError: nil can't be coerced into BigDecimal 

如以上所述subtotal方法失敗,並轉換錯誤。在subtotal我檢查了line_items.class返回的類型,得到Array。如果我更新的subtotal的定義,下列任一,該方法的工作原理:

line_items.to_a.sum(&:price) 
#=> #<BigDecimal:7ff4d34ca7c8,'0.0',9(36)> 

line_items.map(&:price).sum 
#=> #<BigDecimal:7ff4d3373b40,'0.0',9(36)> 

爲什麼的line_items.sum(&:price)初始定義失敗?

+0

什麼類型(類)價格返回? line_items [0] .price.class? – Roger

+0

它是'BigDecimal' –

+0

奇怪。我運行1.9.3和Rails 3.2.1,但它工作正常。你確定所有記錄都返回同一個班級嗎?也許循環的價格,並檢查每個類。 – Roger

回答

0

這似乎是Rails中的一個錯誤(至少在3.2.8中)。

在Rails 3.2.8中,has_many關聯動態定義了collection.sum。 雖然這不反映在A Guide to Active Record AssociationsActiveRecord::Associations::ClassMethods API docs;它簡要列在API的「集合關聯(一對多/多對多)」 圖表下,但未再次引用。

根據code,它總是會嘗試使用SQL sum命中數據庫。 但是,在這個特定的情況下,模型不會被保存。所以在數據庫中沒有什麼 。

因此,要清除了一點:

account.line_items.sum(&:price)  # Uses Collection#sum, goes to database 
account.line_items.map.sum(&:price) # Uses Enumerable#map then Enumerable#sum 

這已經issue #7928下登錄;這與issue #5215: "finders and scopes on has_many association on new object incorrectly query db for null foreign keys"相關。