我有这个代码适用于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 }
}
答案 0 :(得分: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
。