I am trying to create a simple add to cart with Ruby on Rails and I having an issue to display a simple link to cart that has the last id of the user that just added an item to the cart. Simple I getting this error:
No route matches {:action=>"show", :controller=>"carts", :id=>nil}, missing required keys: [:id]
This is my link to the cart and it the place where I am getting the error
<%= link_to 'Cart', cart_path(@cart), class: 'header__cart_link' %>
Routs look same as they should be, I am calling it
resources :carts
In console rake routes
carts GET /carts(.:format) carts#index
POST /carts(.:format) carts#create
new_cart GET /carts/new(.:format) carts#new
edit_cart GET /carts/:id/edit(.:format) carts#edit
cart GET /carts/:id(.:format) carts#show
PATCH /carts/:id(.:format) carts#update
PUT /carts/:id(.:format) carts#update
DELETE /carts/:id(.:format) carts#destroy
Also, I am using a line_items controller to create a reference for the cart so that I making a relation of the product and cart in the line_items
class CartsController < ApplicationController
before_action :set_cart, only: %i[show edit update destroy]
rescue_from ActiveRecord::RecordNotFound, with: :invalid_cart
load_and_authorize_resource
def index
@carts = Cart.all
end
def new
@cart = Cart.new
end
def create
@cart = Cart.new(cart_params)
respond_to do |format|
if @cart.save
format.html { redirect_to @cart, notice: 'Cart was successfully created.' }
format.json { render :show, status: :created, location: @cart }
else
format.html { render :new }
format.json { render json: @cart.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if @cart.update(cart_params)
format.html { redirect_to @cart, notice: 'Cart was successfully updated.' }
format.json { render :show, status: :ok, location: @cart }
else
format.html { render :edit }
format.json { render json: @cart.errors, status: :unprocessable_entity }
end
end
end
def destroy
# @cart.destroy if @cart.id == session[:cart_id]
@cart.destroy
session[:cart_id] = nil
respond_to do |format|
format.html { redirect_to root_path, notice: 'Cart was successfully emptied.' }
format.json { head :no_content }
end
end
def empty_cart
if [email protected]?
redirect_to cart_path(@cart)
else
redirect_to cart_path(session[:cart_id])
end
end
private
def set_cart
@cart = Cart.find(params[:id])
end
def cart_params
params.fetch(:cart, {})
end
def invalid_cart
logger.error "Attempt to access invalid cart #{params[:id]}"
redirect_to root_path, notice: 'Invalid cart'
end
end
and here the cart controller it self
def create
@cart = Cart.new(cart_params)
respond_to do |format|
if @cart.save
format.html { redirect_to @cart, notice: 'Cart was successfully created.' }
format.json { render :show, status: :created, location: @cart }
else
format.html { render :new }
format.json { render json: @cart.errors, status: :unprocessable_entity }
end
end
end
In my application_controller.rb I handaling the set_cart
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
include CurrentCart
before_action :set_cart
# before_filter :configure_permitted_parameters, if: :devise_controller?
before_action :store_session_data
before_action :clean_session_cart
rescue_from CanCan::AccessDenied do |exception|
if user_signed_in?
redirect_to main_app.root_url, alert: exception.message
else
redirect_to new_user_session_path, alert: exception.message
end
end
protect_from_forgery
protected
def clean_session_cart
Cart.find(session[:cart_id])
rescue ActiveRecord::RecordNotFound
session[:cart_id] = nil
end
def store_session_data
RequestStore.store[:session] = session
end
end
and then I creating a concerns
in the models current_cart.rb
module CurrentCart
extend ActiveSupport::Concern
private
def set_cart
begin
@cart = Cart.find(params[:cart_id] || session[:cart_id])
rescue ActiveRecord::RecordNotFound
@cart = Cart.create
end
session[:card_id] = @cart.id
end
end
@cart
is not initialized forview/layouts/_header.html.erb
.