/ / iteruj i uzyskuj sumę - ruby-on-rails, ruby, model-view-controller

iteruj i uzyskuj sumę - ruby-on-rails, ruby, model-view-controller

Buduję prostą aplikację do faktury. Mam model faktury, który ma wiele pozycji: items i: items belongs_to: invoice.

W odniesieniu do schematu modelu: faktury mają po prostu kolumnę do przechowywania tytułu, a: items dba o wszystkie szczegóły dotyczące ilości i ilości.

Mam indeks faktur, gdzie znajduje się listafaktury są pokazane z ich "całkowitą kwotą". Łączna kwota dla każdej faktury jest ustalana za pomocą metody "quantity_amount_sum", którą skonfigurowałem w modelu pozycji, która pobiera wszystkie pozycje faktury i mnoży ilość przez kwotę, aby określić sumę wszystkich pozycji na fakturze.

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

Problem polega na tym, że próbujemy podsumować "wielki"total "dla strony indeksu (np. dwie faktury, każda z sumą pozycji, faktura nr 1 wynosi 100 USD, faktura nr 2 wynosi 200 USD, a następnie chcę" sumę "faktur, które powinny wynosić 300 USD). Próbowałem iterować przez każdą z faktur, używając "each do" dla sumy, ale udało mi się odzyskać sumę tylko za ostatnią fakturę, nigdy dwie razem.

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

model invoice.rb

 def self.total_val
@@item_amount
end

W ten sposób powstanie suma tylko ostatniej faktury (lub 200 USD), podczas gdy suma powinna wynosić 300 USD.

Odpowiedzi:

0 dla odpowiedzi № 1

Jeśli chcesz sumę obu faktur, możesz zmienić tę linię:

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

do tego:

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

Jednak widzę, że zbliżasz się do pozycji, aby obliczyć całkowitą kwotę faktury. Zachęcam do dodania nowej kolumny o nazwie: total do invoices zamiast tego tabela. Później możesz utworzyć wywołanie zwrotne w swoim Invoice Model:

before_save :update_total

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

Które będą łatwo dostępne i będą się powtarzać w przyszłości, gdy twoje dane będą rosły. Upewnij się też, że masz inne wywołanie zwrotne Item klasa, która aktualizuje powiązane Invoice"s suma w przypadku, gdy element jest edytowany.

Następnie możesz zmienić widok na:

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

Ty też nie musisz pisać return tutaj:

def quantity_amount_sum
self.quantity * self.amount
end

Ruby domyślnie zwraca ostatnie wyrażenie.