4

Context: I have 2 models Order and Item.

I want to calculate Item subtotal based on item.quantity * item.price For now this is done in the view (but not the appropriate place).

<%= number_to_currency(item.quantity * item.price) %>

I also need to calculate the Order total but I'm stuck. I don't have any column for that. What's the best approach? Use the model? Helper or Observer?

For now I managed to have subtotal working through Order helper

def item_subtotal(item)
  item_subtotal = item.quantity * item.price
end

Working Solution:

Item model

def subtotal
  price * quantity
end

In View render <%= item.subtotal %>

Order model

def total_price
  total_price = items.inject(0) { |sum, p| sum + p.subtotal }
end

Order#show view render <%= number_to_currency(@order.total_price) %>

Gaelle
  • 599
  • 2
  • 6
  • 24

3 Answers3

7

On your Item model you could add a subtotal method:

def subtotal
  quantity * price
end

Assuming that you're Order model as a has_many relationship with Item you could map the collection to get a list of prices on the Order model:

def subtotals
  items.map do |i| i.subtotal end
end

Because you're running in a Rails environment you can use the activesupport sum method to get the total on an Order model:

def total
  subtotals.sum
end

Or if you prefer putting it all together:

def total
  items.map do |i| i.subtotal end.sum
end

Then you can use the subtotal on Item and total on Order in your views.

Edit: The view could look like this:

<% for item in @order.items %> <%= item.price %><br/><% end %>
<%= @order.total %>
leonm
  • 6,454
  • 30
  • 38
0

You can Show the item_subtotal by using

and for grand total you can calculate it by

total_price = @order.items.to_a.sum { |item| total = item.product.price*item.quantity }

I think this will work for you.

Pradeep Agrawal
  • 307
  • 2
  • 10
0

Since it is a functionality of the model (you want to calculate something of the item that is self-referential), the more appropriate location is the model itself, so that you can easily use

item.subtotal
Jack
  • 131,802
  • 30
  • 241
  • 343
  • which model: order or item? How does it know that subtotal equals price * quantity? What about total? – Gaelle Oct 16 '11 at 02:55
  • 1
    subtotal should be defined inside `Item` model while the grand total should be calculated inside `Order` total by selecting all the items and calculating their subtotal. – Jack Oct 16 '11 at 03:01
  • Can you please write an example for total and especially how to render in the view. thanks. The order#show view goes like this `<% for item in @order.items %> <%= item.price %>` – Gaelle Oct 16 '11 at 03:09