Forum: Ruby on Rails Inject error when no default value is given?

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.
94cc3e46cfc5bc361e409e2e884ecfa4?d=identicon&s=25 Drew Olson (dfg59)
on 2007-02-02 20:42
I have an Event model which has_many :attendees. My Attendee model has a
column called participants, which is an integer representing the number
of participants in the attendees party. I want to sum the total number
of participants for a given event. This works fine if I just the default
option of 0 for the method inject, but inject fails if you don't give it
a default. In ruby, injects normal behavior will default the sum to 0 if
you don't provide an argument. See my console output below:

>> myevent = Event.find(1)
=> #<Event:0x34d95ec @attributes={"title"=>"Canned Food Drive",
"date"=>"2007-02-01 12:00:00", "id"=>"1", "description"=>"We need a
least 20 people to sign up for the canned food drive. This will could
toward service hours and will be a great event to help younger scouts
get involved with the community. We will be collecting, sorting and
delivering donated cans.", "rsvp_date"=>"2007-01-15",
"permission_url"=>"/docs/permission.jpg", "location"=>"Saint David's"}>
>> myevent.attendees.inject(0){|sum,att| sum = att.participants}
=> 1
>> myevent.attendees.inject{|sum,att| sum = att.participants}
=> #<Attendee:0x34cc7ac @attributes={"name"=>"Drew Olson",
"event_id"=>"1", "participants"=>"1", "contact"=>"847.942.2606",
"id"=>"1"}>

As you can see, if a default of 0 is not provided, inject returns an
instance of the Attendee class rather than the value in sum. Very
strange...
94cc3e46cfc5bc361e409e2e884ecfa4?d=identicon&s=25 Drew Olson (dfg59)
on 2007-02-02 20:51
> As you can see, if a default of 0 is not provided, inject returns an
> instance of the Attendee class rather than the value in sum. Very
> strange...

My inject statements should have read inject{|sum,att| sum +
att.participants}. I've rerun the code, now I am getting a full-fledged
error when I don't provide a default value:

>> myevent.attendees.inject{|sum,att| sum + att.participants}
NoMethodError: undefined method `+' for #<Attendee:0x34cca90>
        from
/opt/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5618/lib/active_record/base.rb:1848:in
`method_missing'
        from (irb):2
        from
/opt/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5618/lib/active_record/base.rb:1928:in
`inject'
        from
/opt/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5618/lib/active_record/associations/association_proxy.rb:123:in
`each'
        from
/opt/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5618/lib/active_record/associations/association_proxy.rb:123:in
`inject'
        from
/opt/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5618/lib/active_record/associations/association_proxy.rb:123:in
`send'
        from
/opt/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5618/lib/active_record/associations/association_proxy.rb:123:in
`method_missing'
        from
/opt/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4.5618/lib/active_record/associations/has_many_association.rb:98:in
`method_missing'
        from (irb):2
>> myevent.attendees.inject(0){|sum,att| sum + att.participants}
=> 5
5f23b06d22b84ec6c902bf390071a79c?d=identicon&s=25 _Kevin (Guest)
on 2007-02-02 21:07
(Received via mailing list)
On Feb 2, 2:51 pm, Drew Olson <rails-mailing-l...@andreas-s.net>
wrote:
> NoMethodError: undefined method `+' for #<Attendee:0x34cca90>
>         from
> `method_missing'
>         from (irb):2>> myevent.attendees.inject(0){|sum,att| sum + att.participants}
>
> => 5
>
> --
> Posted viahttp://www.ruby-forum.com/.

IIRC,

Calling inject with no parameter copies the first element of the
enumerable into the accumulator.  In this case it fills it with the
first attendee.  It never calls 'participants' on it.

This works fine when you are using it on numbers, but runs into
trouble with more complicated data types.

Doing this would probably work as you expect.

myevent.attendees.map(&:participants).inject {|sum,att| sum + att}

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