Forum: Ruby on Rails Printing running total in do loop

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.
667aed5422143e40584cb07622f284d7?d=identicon&s=25 denied39 (Guest)
on 2009-01-22 10:26
(Received via mailing list)
Ok, so I'm really new to Ruby and Rails. I'm trying to create a home
budget app, and I'm having some difficulties getting a running total
working. I have the following code in my model:
 def running_total
      @total = 0.0
      @transactions = Transaction.find(:all, :conditions =>
["category_id=?", category.id])
      @transactions.each do |transaction|
        @total += transaction.amount.to_f
        return @total
      end
 end

What happens is I get the first expense amount, but it repeats for
every row in the table.
Date            Payee    Amount    Total
2008-12-03   test           17.98    17.98
2008-12-03   test           0.57            17.98
2008-12-03   test           19.04    17.98

This is my first app with Rails, so I'm not sure everything is in the
right place. I created a Ruby script that contains the following:
result = dbh.query("select amount from transactions where category_id
= 6")
 test = 0.0
 result.each do |row|
   test += row[0].to_f
   puts test
 end

The script works like it should, it increments the total after every
pass. Not sure what I'm doing wrong with the Rails portion. Any help
would be great. If you need me to post any more detail, just let me
know.
46f52c33235283752423837b91c581dd?d=identicon&s=25 Norm (Guest)
on 2009-01-22 17:15
(Received via mailing list)
denied39 wrote:
>       end
> right place. I created a Ruby script that contains the following:
> would be great. If you need me to post any more detail, just let me
> know.
>
> >
>
>
Your loop ends with the "return @total" instead of totaling the
transactions.  Move the return down to after the end and I think you
will be happier.

Norm
667aed5422143e40584cb07622f284d7?d=identicon&s=25 denied39 (Guest)
on 2009-01-22 22:38
(Received via mailing list)
Ok, I moved the return @total after the "end", and now I get the
following:

2008-12-03    test    17.98    191.72
2008-12-03   test   0.57           191.72
2008-12-03   test   19.04   191.72

(there are more rows, I just cut it to three for the example)
So, the total works, but it doesn't increment the total after every
row. I seem to get either the first amount, or the sum.
B54c73767addd2a75cf005e3941b7829?d=identicon&s=25 Aldo Sarmiento (sarmiena)
on 2009-01-23 01:49
hmmmnnn. for one, you shouldn't be using an instance variable as it does
not need to live outside the scope of the function. that being said,
there is a better way of handling this anyhow.

Make sure that the tables are normalized, it is the best way to allow
rails to figure out all the associations without your help.

I am assuming that the code above is from an activerecord class called
"Customer" where each customer may have many "transactions"?

If this is the case, make sure that your "transactions" table has a
field called "customer_id".

that way you can do this now:

class Customer < ActiveRecord::Base
    has_many :transactions

    def running_total
        #http://www.ruby-doc.org/core/classes/Enumerable.html#M003160
        transactions.inject{|m,v| m.amount.to_f + v.amount.to_f}
    end
end

class Transaction < ActiveRecord::Base
    belongs_to :customer
end

check this link out on associations:
http://api.rubyonrails.org/classes/ActiveRecord/As...

You can check out what's going on here by using 'script/console' from
within your rails working environment:

aldo@aldo-desktop:~/Documents/ruby/stuffses$ script/console
Loading development environment (Rails 2.1.0)
>> customer = Customer.find_by_id(1)
>> customer.transactions #will list all associated transactions



HTH,

Aldo Sarmiento
5f94b9b346c2aa648a80bc259978e5bc?d=identicon&s=25 Colin Law (Guest)
on 2009-01-23 10:40
(Received via mailing list)
The reason the total is the same on every row rather than being a
running
total is that your code calculates the total once for all all
transactions
of the given category. If you want a running total you will have to have
an
array @totals where the first element is the first transaction, the
second
is that plus the second transaction, the third is that plus the third
transaction and so on, then display this in the view.
Colin

2009/1/22 denied39 <denied39@gmail.com>
667aed5422143e40584cb07622f284d7?d=identicon&s=25 denied39 (Guest)
on 2009-01-23 20:34
(Received via mailing list)
@Aldo - I tried the inject method, and it looks like it might work,
but I get an undefined method "amount" error. It lists the total of
the first two amount in the error, so it is adding, but somewhere it
is failing in the code. I'm not sure if I have things in the right
model or not, so that could be the issue. The customer model you were
referring to is actually a category model. I tried to move the code
from the transaction model to the category model like you described,
but that also failed to work. Which could very well be me not having
the view looking in the right place.

@Colin - I understand what you mean about the array, but I thought the
@total =+ transactions.amount.to_f would increment the total for each
row. Again, this could be my novice understanding of the web (and
Rails) way of programming. Up to this point, I've only ever written
command line scripts for Perl. I'll definitely give the added array a
try and see if I can make that work.

As I struggle through this, I wonder if I'm just really over-thinking
this problem. Do I really need a running total, or would a final sum
be adequate? I'm going to try the solutions everyone proposed before I
scrap the running total idea.

Thanks for you help so far. I'll post my progress later this evening.
This topic is locked and can not be replied to.