Slowboy Slowboy - 2 months ago 10
Ruby Question

Showing Number of Cart Items instead of Cart total price in navbar Rails app

In my rails app I have this code in my

_navbar.html.erb


<% if @cart.total_price > 0 %>
<%= link_to @cart do %>
<i class="fa fa-shopping-cart"> &euro; </i>
<%= @cart.total_price %>
<% end %>

<% else %>
<a href="#" class="menu-cart"><i class="fa fa-shopping-cart"></i> &euro; 0.00</a>
<% end %>


It displays the
@cart.total_price
but I want it to display the total items in the Cart instead.

I'm not sure how to do that

Most of this code is from a Udemy tutorial, but it's getting little bit to much for my experience so I feel kind a lost trying to modify this to my needs.

I've been trying to add the
@product_item
to the above code but with out a luck, can anyone take a look at this and guide me through this.

I have this code in the
application_controller.rb


before_action :set_cart

def set_cart
@cart = Cart.find(session[:cart_id])
rescue ActiveRecord::RecordNotFound
@cart = Cart.create
session[:cart_id] = @cart.id
end


In the
carts_controller.rb
I have this:

class CartsController < ApplicationController

before_action :set_cart, only: [:show, :destroy]
rescue_from ActiveRecord::RecordNotFound, with: :invalid_cart

def new
@cart = Cart.new
end

def show
@images = ["1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg"]
@random_no = rand(5)
@random_image = @images[@random_no]

end


def destroy
@cart.destroy if @cart.id == session[:cart_id]
session[:cart_id] = nil
redirect_to root_url, notice: 'Your Cart is Empty'
end


private

def set_cart
@cart = Cart.find(params[:id])
end

def cart_params
params[:cart]
end

def invalid_cart
logger_error = 'You are trying to access invalid cart'
redirect_to root_url, notice: 'Invalid Cart'
end
end


In the
controllers/concerns
I've this file
current_cart.rb


module CurrentCart

private

def set_cart
@cart = Cart.find(session[:cart_id])
rescue ActiveRecord::RecordNotFound
@cart = Cart.create
session[:cart_id] = @cart.id
end
end


Then I have the
product_items_controller.rb
and there is this code:

class ProductItemsController < ApplicationController

include CurrentCart

before_action :set_cart, only: [:create]
before_action :set_product_item, only: [:show, :destroy]

def create

@product = Product.find(params[:product_id])
@product_item = @cart.add_product(@product.id)
if @product_item.save
redirect_to root_url, notice:'Product added to Cart'
else
render :new
end
end

private

def set_product_items
@product_item = ProductItem.find(params[:id])
end

def product_item_params
params.require(:product_item).permit(:product_id)
end

end


And the relevant models are
cart.rb
and
product_item.rb


in the
cart.rb
I have this code:

class Cart < ActiveRecord::Base

has_many :product_items, dependent: :destroy

def add_product(product_id)
current_item = product_items.find_by(product_id: product_id)
if current_item
current_item.quantity += 1
else
current_item = product_items.build(product_id: product_id)
end
current_item
end

def total_price
product_items.to_a.sum{|item| item.total_price}
end

end


And in the
product_item.rb
there is this code:

class ProductItem < ActiveRecord::Base
belongs_to :product
belongs_to :cart
belongs_to :order


def total_price
product.price * quantity
end

end

Answer

You can rewrite the @cart code in the _navbar.html.erb to look like this, it should work just like the previous chunk but shows the product_items.countinstead of the total_price

<% if @cart.product_items.count > 0 %>
  <%= link_to @cart do %> 
  <i class="fa fa-shopping-cart"></i>
  <%= @cart.product_items.count %>
  <% end %>

  <% else %>
     <a href="#" class="menu-cart"><i class="fa fa-shopping-cart"></i> 0 </a>
<% end %>    
Comments