没有路由匹配{:action =>“ show”,:controller =>“ carts”,:id => nil},缺少必需的键:[:id]

时间:2018-11-14 05:21:43

标签: ruby-on-rails ruby-on-rails-5.2

我正在尝试使用Ruby on Rails创建一个简单的添加到购物车,但是我遇到一个问题,无法显示指向购物车的简单链接,该链接具有刚向购物车添加了商品的用户的最后一个ID。 很简单,我收到此错误:

No route matches {:action=>"show", :controller=>"carts", :id=>nil}, missing required keys: [:id]

这是我的购物车链接,也是我收到错误的地方

<%= link_to 'Cart', cart_path(@cart), class: 'header__cart_link' %>

溃败看起来应该是一样的,我称之为

resources :carts

在控制台耙路径中

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

此外,我正在使用line_items控制器为购物车创建引用,以便在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 !@cart.nil?
      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

这是购物车控制器本身

  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

在我的application_controller.rb中,我处理了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

然后在模型current_cart.rb

中创建一个concerns
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

1 个答案:

答案 0 :(得分:0)

@cart未初始化为view/layouts/_header.html.erb

  

在应用程序控制器中设置购物车

class ApplicationController < ActionController::Base
  before_action :set_global_cart

  def set_global_cart
    @global_cart = current_user.cart || current_user.cart.create()
    //something similar & it will be better to use different name instead of @cart
  end
end
相关问题