2012-01-18 16 views
0

私は行合計を持つ表を印刷していますが、列の合計も取得したいと思います。次のコードは機能しません。総計の代わりに、最後の反復の値が表示されます。Rails 3.配列からの合計を取得する

<% @shipments.each do |shipment| %> 
    <tr> 
    <td style="text-align:center;"><%= shipment.file_number %></td> 
    <td><%= shipment.shipper.company_name %></td> 
    <td><%= shipment.hbl %></td> 
    <td><%= shipment.status %></td> 
    <td><%= shipment.age %></td> 
    <td><%= shipment.invoice.read_issued_at unless shipment.invoice.nil? %></td> 
    <td><%= number_to_currency shipment.invoice.customer_total unless shipment.invoice.nil? %></td> 
    <td><%= number_to_currency shipment.invoice.customer_amount_paid unless shipment.invoice.nil? %></td> 
    <td><%= number_to_currency shipment.invoice.customer_open_balance unless shipment.invoice.nil? %></td> 
    </tr> 
    <% 
    grand_customer_total = 0 
    grand_customer_amount_paid = 0 
    grand_customer_open_balance = 0 
    grand_customer_total += shipment.invoice.customer_total 
    grand_customer_amount_paid += shipment.invoice.customer_amount_paid 
    grand_customer_open_balance += shipment.invoice.customer_open_balance 
    %> 
    <% if @shipments.last == shipment %> 
    <tr> 
    <td></td> 
    <td></td> 
    <td></td> 
    <td></td> 
    <td></td> 
    <th>Totals</th> 
    <td><%= number_to_currency grand_customer_total %></td> 
    <td><%= number_to_currency grand_customer_amount_paid %></td> 
    <td><%= number_to_currency grand_customer_open_balance %></td> 
    </tr> 
    <% end %> 

答えて

2

あなたのコードがうまくいかない理由は、変数がブロック内で定義されているため、ブロックローカル変数とみなされるからです。ブロックが終了すると、それらの変数はクリアされるようにマークされます。各反復はそれらの変数を再定義する。変数が毎回定義されていないため、各反復で変数を0に再割り当てするのに役立つわけでもありませんが、ここでも有効になりません。

ブロックの前に変数を定義するだけでも問題ありませんが、それでもかなり面倒です。 Rubyのイディオムや規約はきれいで整然としたコードに重点を置いているので、私はそれを離れて代わりにこれらの数値を別々に、おそらくあなたのコントローラーで計算します。

<tr> 
    <td colspan="5"></td> 
    <th>Totals</th> 
    <td><%= number_to_currency @totals[:overall] %></td> 
    <td><%= number_to_currency @totals[:paid] %></td> 
    <td><%= number_to_currency @totals[:balance] %></td> 
</tr> 
2

ループのたびに総計をゼロに設定します。ループの前に初期化を上に移動します。

1

あなたは

を介してそれらを毎回リセットされているので、あなたが

@shipments.inject(0) { |sum, shipment| sum + shipment.invoice.customer_total } 

またはちょうど@shipments.eachループの外grand_customer_*オブジェクトを初期化し、あなたのコードのレイアウトを維持したいルビーinject

何かを使用することができます

1
<% 
grand_customer_total = 0 
grand_customer_amount_paid = 0 
grand_customer_open_balance = 0 
%> 
<% @shipments.each do |shipment| %> 
<tr> 
    <td style="text-align:center;"><%= shipment.file_number %></td> 
    <td><%= shipment.shipper.company_name %></td> 
    <td><%= shipment.hbl %></td> 
    <td><%= shipment.status %></td> 
    <td><%= shipment.age %></td> 
    <td><%= shipment.invoice.read_issued_at unless shipment.invoice.nil? %></td> 
    <td><%= number_to_currency shipment.invoice.customer_total unless shipment.invoice.nil? %></td> 
    <td><%= number_to_currency shipment.invoice.customer_amount_paid unless shipment.invoice.nil? %></td> 
    <td><%= number_to_currency shipment.invoice.customer_open_balance unless shipment.invoice.nil? %></td> 
</tr> 
<% 
grand_customer_total += shipment.invoice.customer_total 
grand_customer_amount_paid += shipment.invoice.customer_amount_paid 
grand_customer_open_balance += shipment.invoice.customer_open_balance 
%> 
<% if @shipments.last == shipment %> 
<tr> 
    <td></td> 
    <td></td> 
    <td></td> 
    <td></td> 
    <td></td> 
    <th>Totals</th> 
    <td><%= number_to_currency grand_customer_total %></td> 
    <td><%= number_to_currency grand_customer_amount_paid %></td> 
    <td><%= number_to_currency grand_customer_open_balance %></td> 
</tr> 
<% end %> 
:代わりに @shipments.last比較を使用しての

@totals = { 
    :overall => @shipments.reduce(0) { |total, shipment| total + shipment.invoice.customer_total }, 
    :paid => @shipments.reduce(0) { |total, shipment| total + shipment.invoice.customer_amount_paid }, 
    :balance => @shipments.reduce(0) { |total, shipment| total + shipment.invoice.customer_open_balance } 
} 

はその後、あなたは自分の出荷テーブルの出力後に次の操作を行うことができます

関連する問題