Forum: Ruby on Rails Enumerable sum oddity

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Morten (Guest)
on 2007-03-22 14:53
(Received via mailing list)
Hi.

In this setup "account has_many :consultations". Can anyone explain
the following behaviour to me? Rails 1.2.2. The "sum" method should
return 0 for an empty array.

>> a = Account.find(1)
=> #<Account:0x39c80a8 @attributes={...}
>> a.consultations
=> []
>> a.consultations.sum(&:foo)
ArgumentError: wrong number of arguments (1 for 2)
        from ./script/../config/../config/../vendor/rails/activerecord/
lib/active_record/associations/has_many_through_association.rb:110:in
`calculate'
        from ./script/../config/../config/../vendor/rails/activerecord/
lib/active_record/associations/has_many_through_association.rb:110:in
`send'
        from ./script/../config/../config/../vendor/rails/activerecord/
lib/active_record/associations/has_many_through_association.rb:110:in
`method_missing'
        from ./script/../config/../config/../vendor/rails/activerecord/
lib/active_record/base.rb:946:in `with_scope'
        from ./script/../config/../config/../vendor/rails/activerecord/
lib/active_record/associations/has_many_through_association.rb:110:in
`method_missing'
        from ./script/../config/../config/../vendor/rails/activerecord/
lib/active_record/associations/has_many_through_association.rb:102:in
`sum'
        from (irb):15

But if I use a hard coded empty array, things work:

>> [].sum(&:foo)
=> 0

What's happening? Thanks.

Morten
Trevor S. (Guest)
on 2007-03-22 19:41
(Received via mailing list)
Hey Morten,

yeah, I feel your pain sharply, because it happened to me too.

It turns out that associations favor the ActiveRecord sum method
(which issues an sql query) over the Enumerable sum method (which
iterates over the collection).

Here's something that's not fully tested by me but you can stick it
in your environment.rb and see how it works for you.  Once I test it
better I'll submit it as a patch.

http://pastie.caboo.se/48812

When you don't pass a block to sum() it'll end up delegating to the
AR calculate() method, otherwise it iterates.

so:

collection.sum :id # => issues an sql query via calculate()
collection.sum &:id => iterates over the collection due to :id.to_proc

HTH
Trevor
Morten (Guest)
on 2007-03-22 23:04
(Received via mailing list)
Thanks Trevor. I also got informed that an explicit .to_a will work
(which it did for me):

collection.to_a.sum(&:id)

Br,

Morten
This topic is locked and can not be replied to.