Reputation: 75
I am trying to build a simple cart based on sessions. I am using this youtube tutorial as an template: vid#4 here https://www.youtube.com/watch?v=WRVwfVUaj_Y and vid#5 here https://www.youtube.com/watch?v=HSMqi913SL4.
I am getting the same error that he gets in vid#5 at , but he doesn't show how he fixed it.
Here are my routes:
get '/cart' => 'cart#index'
get '/cart/clear' => 'cart#clearCart'
get '/cart/:id' => 'cart#add'
And here is my cart_controller.rb:
class CartController < ApplicationController
def add
id = params[:id]
if session[:cart] then
cart = session[:cart]
else
session[:cart] = {}
cart = session[:cart]
end
if cart[id] then
cart[id] = cart[id] + 1
else
cart[id] = 1
end
redirect_to :action => :index
end
def clearCart
session[:cart] = nil
redirect_to :action => :index
end
def index
if session[:cart] then
@cart = session[:cart]
else
@cart = {}
end
end
end
Here is my cart/index.html.erb page:
<h3>Your Shopping Cart</h3>
<%= link_to "Empty Your Cart", cart_clear_path %>
<% total = 0 %>
<% @cart.each do | id, quantity | %>
<% product = Product.find_by_id(id)%>
<div class="row">
<div class="col-lg-3 col-md-3 col-sm-6 col-xs-12" >
<div class="product_text">
<h3><%= product.name %></h3>
<h3><%= product.description %></h3>
<h3>$<%= product.price %></h3>
</div>
</div>
</div>
<%end%>
I am very confused because I know the Product object exists, but I am still getting the error in title.
Upvotes: 0
Views: 107
Reputation: 75
Thanks to everyone for the help, but I found the solution. I needed to sanitize the id with .gsub('"', '') before I could pass it through to find_by_id.
This worked:
<% @cart.each do | id , qty | %>
<% p = Product.find_by_id(id.gsub('"', '')) %>
<%= p.name %> <%= qty %>
<%end%>
Upvotes: 0
Reputation: 1428
You could try assigning the cart variable back to the session after you do the addition
def add
id = params[:id]
cart = session[:cart] || {}
cart[id] = 0 unless cart[id]
cart[id] = cart[id] + 1
session[:cart] = cart
redirect_to :action => :index
end
BTW I don't think if should be included in the language
def index
@cart = session[:cart] || {}
end
The way I would have processed the Product is in the controller. I have reservations about ever seeing the Model inside the view. I'm not sure if this is a design pattern or not, but I would pass an array of products to the view rather than a collection of Arrays to look up. I know for a fact this helps the test-ability of the code.
# app/controllers/cart_controller.rb #should be carts_controller for RAILS convention
def index
@cart = []
session[:cart].each do |product_id, qty|
@cart << {product: Product.find(product_id) , qty: qty}
end
end
To use this in the view just @cart.each do |c| <%=c.product.name %> <%=c.qty %>
Upvotes: 1