# Strange Sum issue

**URL:** <https://www.ruby-forum.com/t/strange-sum-issue/119627>\
**Category:** Rails\
**Created:** [November 8, 2007, 5:30pm UTC](https://www.ruby-forum.com/t/strange-sum-issue/119627 "2007-11-08T17:30:13Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![johnt519](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/cab0a1/32.png) [@johnt519](https://www.ruby-forum.com/u/johnt519)\
**Post date:** [November 8, 2007, 5:30pm UTC](https://www.ruby-forum.com/t/strange-sum-issue/119627/1 "2007-11-08T17:30:13Z")

</div>

Hello,

This may just be my misunderstanding something, but I’m seeing  
something strange.

I have a model, Ticket, that in the database table ‘tickets’ has a  
field, let’s say ‘seats’.

I can do a Find and retrieve the items:

t = Ticket.find :all

Then do a sum to get the total seats:  
s = t.sum(&:seats)

and that returns the correct sum.

Playing in the console, I did:  
t.sum(&:seats)

and while returning the correct sum, it also changed the ‘t’ variable  
to be just the final item in the array. Is this correct? The sum is  
just doing an ‘inject’, which I didn’t think altered the original  
array, but maybe I’m wrong?

And here’s a second question, say I want to use the found items, but  
restrict the sum to a subset - total all seats that have been sold. I  
could do it by doing another find, but can I use .inject with a  
condition, so I don’t have to requery the database?

Thanks!

---

<div class="post-metadata">

**Author:** ![johnt519](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/cab0a1/32.png) [@johnt519](https://www.ruby-forum.com/u/johnt519)\
**Post date:** [November 8, 2007, 5:54pm UTC](https://www.ruby-forum.com/t/strange-sum-issue/119627/2 "2007-11-08T17:54:50Z")

</div>

Hmm, not sure on the console based sum findings, I don’t see the same  
behavior. On your other question, the sum methods, etc all use  
ActiveRecord::Calculations#calculate and it will take a conditions  
parameter. See:  
[http://api.rubyonrails.org/classes/ActiveRecord/Calculations/ClassMethods.html#M000969](http://api.rubyonrails.org/classes/ActiveRecord/Calculations/ClassMethods.html#M000969)

If your condition is fairly simple and you can just use inject manually:

t = Ticket.find :all

s = t.inject{|sum,n| n.column\_you\_care\_about == ‘some\_value’ ? sum +  
n.column\_to\_add : 0}

-Bill

John T. wrote:

> t = Ticket.find :all  
> to be just the final item in the array. Is this correct? The sum is
> 
> >

–  
Sincerely,

William P.

---

<div class="post-metadata">

**Author:** ![johnt519](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/cab0a1/32.png) [@johnt519](https://www.ruby-forum.com/u/johnt519)\
**Post date:** [November 8, 2007, 6:11pm UTC](https://www.ruby-forum.com/t/strange-sum-issue/119627/3 "2007-11-08T18:11:12Z")

</div>

On Nov 8, 2007 11:53 AM, William P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> s = t.inject{|sum,n| n.column\_you\_care\_about == ‘some\_value’ ? sum +  
> n.column\_to\_add : 0}
> 
> -Bill

Thanks. I think the weird console behavior may have just been my  
stupidity 🙂 I think I was using the array inside the inject so it was  
just assigning to itself. Duh.

I’m trying the simple inject, but for some reason it isn’t totaling  
the column. I’m using:

s= t.inject(0) {|total,n| n.picked\_up ? (total + n.seats) : 0}

but it’s always coming out 0. (seats is a boolean, and I’m (for now)  
using sqlite, so the actual data is ‘t’ or ‘f’ - but looking at one  
record displays correctly - t[2].picked\_up is true) I tried using  
n.picked\_up? and n.picked\_up == true

Doing: t[2].picked\_up ? “Y” : “N” correctly returns “Y”

Thanks,

jt

---

<div class="post-metadata">

**Author:** ![johnt519](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/cab0a1/32.png) [@johnt519](https://www.ruby-forum.com/u/johnt519)\
**Post date:** [November 8, 2007, 6:17pm UTC](https://www.ruby-forum.com/t/strange-sum-issue/119627/4 "2007-11-08T18:17:03Z")

</div>

On Nov 8, 2007 11:29 AM, John T. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> t = Ticket.find :all
> 
> Then do a sum to get the total seats:  
> s = t.sum(&:seats)

It is _much_ more efficient to use the AR calculation methods:

s = Ticket.sum(:seats)

The first one retrieves _all_ of the rows and instantiates an AR  
object for each. The second issues a single query that returns one  
number.

> and that returns the correct sum.
> 
> Playing in the console, I did:  
> t.sum(&:seats)
> 
> and while returning the correct sum, it also changed the ‘t’ variable  
> to be just the final item in the array. Is this correct? The sum is  
> just doing an ‘inject’, which I didn’t think altered the original  
> array, but maybe I’m wrong?

Dunno. I don’t see that behavior. The sum() method you’re using there  
is not the ActiveRecord::Base.sum method, but the Enumerable#sum  
method added by active support.

---

<div class="post-metadata">

**Author:** ![johnt519](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/cab0a1/32.png) [@johnt519](https://www.ruby-forum.com/u/johnt519)\
**Post date:** [November 8, 2007, 6:22pm UTC](https://www.ruby-forum.com/t/strange-sum-issue/119627/5 "2007-11-08T18:22:19Z")

</div>

On 8 Nov 2007, at 17:10, John T. wrote:

> s= t.inject(0) {|total,n| n.picked\_up ? (total + n.seats) : 0}
> 
> but it’s always coming out 0. (seats is a boolean, and I’m (for now)  
> using sqlite, so the actual data is ‘t’ or ‘f’ - but looking at one  
> record displays correctly - t[2].picked\_up is true) I tried using  
> n.picked\_up? and n.picked\_up == true

the result of your block needs to be the running total - not the value  
of the individual term, ie

n.picked\_up ? (total + n.seats) : total

Fred

---

<div class="post-metadata">

**Author:** ![johnt519](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/cab0a1/32.png) [@johnt519](https://www.ruby-forum.com/u/johnt519)\
**Post date:** [November 8, 2007, 6:25pm UTC](https://www.ruby-forum.com/t/strange-sum-issue/119627/6 "2007-11-08T18:25:51Z")

</div>

On Nov 8, 2007 12:21 PM, Frederick C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> 

> the result of your block needs to be the running total - not the value  
> of the individual term, ie
> 
> n.picked\_up ? (total + n.seats) : total
> 
> Fred

Ahhh… thanks for the clarification… I had a feeling I was missing  
something simple 🙂

---

<div class="post-metadata">

**Author:** ![johnt519](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/cab0a1/32.png) [@johnt519](https://www.ruby-forum.com/u/johnt519)\
**Post date:** [November 8, 2007, 6:22pm UTC](https://www.ruby-forum.com/t/strange-sum-issue/119627/7 "2007-11-08T18:22:19Z")

</div>

On Nov 8, 2007 12:16 PM, Bob S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > 
> 
> The first one retrieves _all_ of the rows and instantiates an AR  
> object for each. The second issues a single query that returns one  
> number.

True, but I had already performed the Find that would then be passed  
along to my view, so I figured one less trip to the database - and if  
I also want a sum of seats not picked up, I’d then make yet another  
trip to the DB.

> Dunno. I don’t see that behavior. The sum() method you’re using there  
> is not the ActiveRecord::Base.sum method, but the Enumerable#sum  
> method added by active support.

Yeah, I think that was just my dumb error.

I also got the .inject method to work by doing instead:

s= t.inject(0) {|total,n| total + (n.picked\_up ? n.seats : 0)}

---

<div class="post-metadata">

**Author:** ![johnt519](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/cab0a1/32.png) [@johnt519](https://www.ruby-forum.com/u/johnt519)\
**Post date:** [November 8, 2007, 6:46pm UTC](https://www.ruby-forum.com/t/strange-sum-issue/119627/8 "2007-11-08T18:46:54Z")

</div>

Sorry Tom, this was my fault. There way a typo in my original post. Glad  
you got it working.

-Bill

John T. wrote:

> > 
> 
> Ahhh… thanks for the clarification… I had a feeling I was missing  
> something simple 🙂
> 
> >

–  
Sincerely,

William P.
