Rails 用户购物车问题

Rails Issue with User Cart

我有一个 Rails 客户的购物车,它可以工作,但仅在第二次尝试 'add-to-cart' 时有效。

所以每次我点击'add to cart',第一次购物车都是空的。但是在第二次尝试时,该项目被添加到购物车。

我做错了什么?

这是客户控制器代码:

 class Customer::CartsController < ApplicationController
   before_action :authenticate_user!
   def show
     @cart = if current_user
     current_user.cart ||= Cart.find_by(session[:cart_id])
     session[:cart_id] = nil if current_user.cart.purchased_at
  end
  if session[:cart_id].nil?
    current_user.cart = Cart.create!(user_id: params[:id])
    session[:cart_id] = current_user.cart.id 
  end
  @cart = current_user.cart
  end
end

普通手推车控制器

 class CartsController < ApplicationController
 skip_before_action :authorize, only: [:create, :update, :destroy]
 before_action :set_cart, only: [:show, :edit, :update, :destroy]
 rescue_from ActiveRecord::RecordNotFound, with: :invalid_cart

 def index
  @carts = Cart.all
 end

def show
end

def new
 @cart = Cart.new
end

def edit
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]
  session[:cart_id] = nil
 end
 respond_to do |format|
  format.html { redirect_to root_path, notice: 'Your Cart is currently empty.' }
  format.json { head :no_content }
 end
end

private
  # Use callbacks to share common setup or constraints between actions.
 def set_cart
  @cart = Cart.find(params[:id])
end

# Never trust parameters from the scary internet, only allow the white list through.
def cart_params
  params[: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
product = Product.find(params[:product_id])
@line_item = @cart.add_product(product.id, params[:size])

respond_to do |format|
  if @line_item.save
    format.html { redirect_to customer_cart_path }
    format.json { render :show, status: :created, location: @line_item }
  else
    format.html { render :new }
    format.json { render json: @line_item.errors, status: :unprocessable_entity }
  end
end
end

如有任何帮助,我们将不胜感激。提前致谢!

我认为此代码在 Customer::CartsController show action

中是错误的
  @cart = if current_user
    current_user.cart ||= Cart.find_by(session[:cart_id])
    session[:cart_id] = nil if current_user.cart.purchased_at
  end

那将永远@cart == nil

我觉得应该是这样的

  @cart = if current_user
    current_user.cart ||= Cart.find_by(session[:cart_id])
    session[:cart_id] = nil if current_user.cart.purchased_at
    current_user.cart
  end

if语句的最后一部分需要return将要赋值给@cart

的对象

之前在购物车上工作时我遇到了同样的问题,据我所知它来自应用程序控制器中的 current_cart 方法

我最后把它改成了这个

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

也在@cart.add_ 之前...我在我的 lineitems 控制器创建方法中调用了该方法

@cart = current_cart

编辑 1

这是我的 lineitems 创建方法 如果有 none

,我认为你错过了购物车的创建
@lineitem = Lineitem.new(lineitem_params)
@cart = current_cart
item = Item.find(lineitem_params[:item_id])
@lineitem = @cart.addItem(item.id,@lineitem.quantity)

如果没有看到完整的代码,很难确切地说出这里发生了什么。例如,问题主要是关于尝试将产品添加到购物车时发生的错误,但未显示 add_product 方法的定义。

我可以提供一些应该有所帮助的建议。首先,Customer::CartsControllershow 方法很难遵循。我重构了它以删除不必要的嵌套 if 语句,并减少条件语句的数量。

class Customer::CartsController < ApplicationController
  before_action :authenticate_user!

  def show
    return unless current_user

    current_user.cart ||= Cart.find(session[:cart_id])

    # if the cart has already been purchased, reset to a new cart
    if current_user.cart.purchased_at
      current_user.cart = Cart.create!(user_id: params[:id])
      session[:cart_id] = current_user.cart.id 
    end

    @cart = current_user.cart
  end
end

其次,在处理这样的错误时,您应该发现自己有一个更具体的问题(如果不是您问题的答案的话)。为了得出这样一个特定的问题,您需要进行调试以找出问题所在。您可以通过几种方式做到这一点:

  1. 最简单的选择是在您的代码中放置一些 "probe" 语句。比如点击加入购物车时需要确认在Customer::CartsController show action中是否设置了purchased_at值,可以这样写puts "purchased_at is set" 在 if 语句的主体内。输出将显示在 Rails 服务器输出中,您可以在另一个 window 中观看,同时在网络浏览器中与您的站点交互。

  2. 首选选项是使用调试器。我推荐 pry,您可以在此处找到和阅读:https://github.com/nixme/pry-debugger.

您应该尝试使用这些技术中的任何一种来做的是找出在运行时发生的事情与您对代码应该完成的事情的期望不符,或者什么会促进您作为用户期望的行为.最终,这通常会导致隔离出没有意义的特定代码区域,从而使问题变得容易得多。