Reputation: 12663
In a Rails 3.2 app I have defined two methods that perform a calculation and return a big decimal value.
Def Func1
Model1.price * Model1.qty
End
Def Func2
Model2.price * Model2.qty
End
I don't know if this relevant, but the :qty field is a counter cache column recording the number of associated has_many records.
I now want to calculate the sum of Func1 and Func2. If I try
Def FuncTotal
Func1 + Func2
End
it returns the two values concatenated, not the sum. i.e. if Func1=15.45 and Func2=24.76, then FuncTotal=15.4524.76.
I also tried
Def FuncTotal
Func1.to_s + Func2.to_s
End
But this also concatenates.
I assume this issue is occurring because the calculation is based on BigDecimal values. In which case it seems strange to me that the price*qty calculation returns the correct product.
How can I add two BigDecimal values together?
Many thanks
EDIT
This is an example console output
> 1=Model1.find(1)
=> #<Model1 id:1......
> 2.Model2.find(2)
=> #<Model2 id:2....
> 1total=1.func1
=> [#<BigDecimal:10a5cd888,'0.25E4',9(36)>]
> 2.total=2func2
=> [#<BigDecimal:10a5c7348,'0.5E3',9(36)>]
> 1+2
=> [#<BigDecimal:10a5cd888,'0.25E4',9(36)>, #<BigDecimal:10a5c7348,'0.5E3',9(36)>]
Strange!
EDIT
My columns are defined as follows.
Price is the same in both models
t.decimal "price", :precision => 12, :scale => 2
Quantity is more or less the same in both models
t.integer "model1_children_count", :default => 0
and in the child model
belongs_to :model1, :counter_cache => true
EDIT
The full Func1 and Func2 is as follows, located within a parent model that has_many Model1s and Model2s.
Class Parent
def total_cost_of_model1
model1s.collect { |model1s| model1.price * model1.quantity }
end
end
Upvotes: 1
Views: 2098
Reputation: 21604
Your total cost function is calling collect
which returns an array, which when concatenated will return a concatenated array. You have to return the correct type(BigDecimal) if you want to add it up using "+"
Upvotes: 2
Reputation: 11385
Are you sure they're BigDecimals? I'm actually getting the correct behavior here.
irb(main)> a = BigDecimal.new("1")
=> #<BigDecimal:102773230,'0.1E1',9(18)>
irb(main)> b = BigDecimal.new("2")
=> #<BigDecimal:100dd1a48,'0.2E1',9(18)>
irb(main)> c = a + b
=> #<BigDecimal:1026502e0,'0.3E1',9(27)>
irb(main)> c.to_i
=> 3
Upvotes: 0