Rails 3.如何使用has_many关系减少?

时间:2012-08-30 21:47:51

标签: ruby-on-rails ruby

我有这个代码适用于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 }
  }

1 个答案:

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