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 回答