迭代并获得总和

时间:2014-10-13 05:27:56

标签: ruby-on-rails ruby model-view-controller

我正在构建一个简单的发票应用。我有一个发票型号has_many:items和:items belongs_to:invoice。

就模型架构而言,:发票只有一个用于存储标题的列,并且:items负责处理所有(定价)金额和数量的详细信息。

我有一张发票索引,其中会显示一张发票清单,其中包含"总金额"。每张发票的总金额通过" quantity_amount_sum"我在物料模型中设置的方法,它采用发票的所有项目,并将数量乘以金额,以确定发票上所有项目的总和。

model:item.rb

def quantity_amount_sum
   return self.quantity * self.amount
end 

index.html.erb

<% @invoices.each do |invoice| %>
$<%= invoice.item_amount.sum.floor %>
<% end %>

model invoice.rb

  def item_amount
  @@item_amount = self.items.map(&:quantity_amount_sum)
  end

问题在于试图总结一个&#34;总计&#34;对于索引页面(例如:两个发票,每个都有一个项目总和。发票#1总计100美元,发票#2总计200美元。然后我想要一个&#34;总共&#34;发票,应该是300美元)。我尝试使用&#34迭代每张发票;每个都做&#34;总计,但我只能检索最后一张发票的金额,而不是两者合计。

$<%= @invoices.total_val.each.sum %>

model invoice.rb

 def self.total_val
     @@item_amount
  end

这将产生最后一张发票(或200美元)的总和,而总额应为300美元。

1 个答案:

答案 0 :(得分:0)

如果您想要两张发票的总和,那么您可以更改此行:

<% @invoices.each do |invoice| %>
$<%= invoice.item_amount.sum.floor %>
<% end %>

到此:

$<%= @invoices.map(&:item_amount).flatten.sum %>

但是,我发现您正在接近计算发票总金额的项目。我建议您在total表格中添加一个名为invoices的新列。之后,您可以在Invoice模型中创建回调:

before_save :update_total

def update_total
  self.total = self.items.map{|i| i.quantity_amount_sum }.sum
end

随着数据的增长,将来很容易访问和迭代。此外,请确保您在Item课程中有另一个回调,以便在正在编辑项目的情况下更新相关的Invoice总计。

然后您的观点可以更改为:

$<%= @invoices.map(&:total).sum %>

此外,您不必在此处写return

def quantity_amount_sum
  self.quantity * self.amount
end 

Ruby默认返回最后一个表达式。