To be able to show the number of items added to the cart you must have proof of all those that you have added. That is why I advise you to use a new variable to save them:
def initialize
@items = {:apple => 10, :oranges => 5 , :grapes => 15, :banana => 20, :watermelon => 50}
@cart = Hash.new(0)
@cost_total = 0
end
@cart
is a hash whose new keys have a default value of 0
. In this way, in add_item_to_cart
you can add an item to the cart if it does not exist, but if it exists, increase the amount by one:
def add_item_to_cart(item)
@cart[item] += 1
@cost_total += @items[item]
end
To show the cart you can do something like this:
def show
@cart.each do |item, cantidad|
puts "#{cantidad} #{item}: #{cantidad * @items[item]}$"
end
end
The shopping cart is traversed, to show each item, along with its quantity and price (number of items * item value). When executing this:
cart = ShoppingCart.new
cart.add_item_to_cart(:apple)
cart.add_item_to_cart(:banana)
cart.add_item_to_cart(:banana)
cart.show
We get:
1 apple: 10$
2 banana: 40$
PD: As an extra, a more "rubista" way to calculate the total cost, would be to use a method that returns the price instead of using a variable. What is the advantage? Well, if in the future you want to add a new method that would allow the customer to remove an item from the cart, it would be much easier to update the correct price:
def cost
@cart.inject(0) { |sum, (k,v)| sum + v * @items[k] }
end
At first glance, it seems a very strange method, does not it? inject
allows you to perform arithmetic operations with the data. In this case, the objective is to add the price of all the items. sum
is initially worth 0
, and it is added to the number of items in the cart multiplied by its value, where k
and v
are the key and the value of @cart
.