1

で動作するこのコードがありますshipment has one invoiceが、今はに変更する必要がありましたshipment has many invoices。新しい関連付けを反映するように次のコードを変更するにはどうすればよいですか?

@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 }
  }
4

1 に答える 1

2

私はこのようなことをします:

# collect all the invoices at once
invoices = @shipments.map(&:invoices).flatten

@totals = {
  # collect all the customer_totals and sum them... repeat
  :overall => invoices.map(&:customer_total).reduce(0, :+),
  :paid    => invoices.map(&:customer_amount_paid).reduce(0, :+),
  :balance => invoices.map(&:customer_open_balance).reduce(0, :+)
}

注:Enumerable#reduceは、の他の多くのメソッドとともにEnumerable、メソッドまたは演算子を指定するブロックまたはシンボルを操作する機能を備えています。これにより、次のように置き換えることができ[1,2,3,4,5].reduce{ |sum, x| sum + x }ます[1,2,3,4,5].reduce(:+)

また、引数が指定されていない場合、コレクションの最初の値がメモの初期値であると見なされます。

toklandが指摘しているように、配列が空の場合は、メモの初期値を0として渡す必要があります。これにより、を取得できなくなります@totals[:balance] == nil

于 2012-08-30T21:52:52.293 に答える