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::CartsController
的 show
方法很难遵循。我重构了它以删除不必要的嵌套 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
其次,在处理这样的错误时,您应该发现自己有一个更具体的问题(如果不是您问题的答案的话)。为了得出这样一个特定的问题,您需要进行调试以找出问题所在。您可以通过几种方式做到这一点:
最简单的选择是在您的代码中放置一些 "probe" 语句。比如点击加入购物车时需要确认在Customer::CartsController show action中是否设置了purchased_at
值,可以这样写puts "purchased_at is set"
在 if 语句的主体内。输出将显示在 Rails 服务器输出中,您可以在另一个 window 中观看,同时在网络浏览器中与您的站点交互。
首选选项是使用调试器。我推荐 pry
,您可以在此处找到和阅读:https://github.com/nixme/pry-debugger.
您应该尝试使用这些技术中的任何一种来做的是找出在运行时发生的事情与您对代码应该完成的事情的期望不符,或者什么会促进您作为用户期望的行为.最终,这通常会导致隔离出没有意义的特定代码区域,从而使问题变得容易得多。
我有一个 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::CartsController
的 show
方法很难遵循。我重构了它以删除不必要的嵌套 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
其次,在处理这样的错误时,您应该发现自己有一个更具体的问题(如果不是您问题的答案的话)。为了得出这样一个特定的问题,您需要进行调试以找出问题所在。您可以通过几种方式做到这一点:
最简单的选择是在您的代码中放置一些 "probe" 语句。比如点击加入购物车时需要确认在Customer::CartsController show action中是否设置了
purchased_at
值,可以这样写puts "purchased_at is set"
在 if 语句的主体内。输出将显示在 Rails 服务器输出中,您可以在另一个 window 中观看,同时在网络浏览器中与您的站点交互。首选选项是使用调试器。我推荐
pry
,您可以在此处找到和阅读:https://github.com/nixme/pry-debugger.
您应该尝试使用这些技术中的任何一种来做的是找出在运行时发生的事情与您对代码应该完成的事情的期望不符,或者什么会促进您作为用户期望的行为.最终,这通常会导致隔离出没有意义的特定代码区域,从而使问题变得容易得多。