You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让session[:cart_size]在用户重新登录后保持持久化?

问题描述

应用中购物车商品数量(cart_size)在用户同一会话内可正常保持,但用户购物车有商品时登出再登录后,购物车图标显示为空,订单视图却仍能看到商品。需要实现cart_size在用户登出再登录后持久化显示。

现有代码

OrderItemsController

class OrderItemsController < ApplicationController
  before_action :authenticate_user!

  def create
    order_item = current_order.order_items.new(article_id: params[:article_id])
    if order_item.save
      session[:cart_size] = current_order.order_items.size
      redirect_to root_path, notice: 'Successfully added to cart.'
    else
      redirect_to root_path, alert: 'Error adding to cart.'
    end
  end

  def destroy
    order_item = OrderItem.find(params[:id])
    order_item.destroy
    session[:cart_size] = current_order.order_items.size
    redirect_to order_item_path, notice: 'Successfully removed from cart.'
  end

  def current_order
    order = Order.where(user_id: current_user.id, status: 'created').order(updated_at: :desc).last
    order || Order.create(user_id: current_user.id)
  end
end

购物车图标调用

<%= session[:cart_size] || 0 %>

订单视图(views/orders/show.html.erb)

<% if @order&.order_items.present? %>
  <% @order.order_items.each do |order_item| %>
    <div><%=order_item.article.title%></div>
<% else %>
  <span>You have no items in your cart</span>
<% end %>
解决方案

问题根源是session[:cart_size]仅存储在当前会话中,用户登出后会话销毁,重新登录时新会话无该值。正确做法是从用户的当前订单实时获取商品数量,而非依赖session。

1. 移除session存储逻辑

修改OrderItemsController,删除所有设置session[:cart_size]的代码:

class OrderItemsController < ApplicationController
  before_action :authenticate_user!

  def create
    order_item = current_order.order_items.new(article_id: params[:article_id])
    if order_item.save
      redirect_to root_path, notice: 'Successfully added to cart.'
    else
      redirect_to root_path, alert: 'Error adding to cart.'
    end
  end

  def destroy
    order_item = OrderItem.find(params[:id])
    order_item.destroy
    redirect_to order_item_path, notice: 'Successfully removed from cart.'
  end

  def current_order
    order = Order.where(user_id: current_user.id, status: 'created').order(updated_at: :desc).last
    order || Order.create(user_id: current_user.id)
  end
end

2. 视图中实时计算购物车数量

修改购物车图标代码,直接从当前用户的订单获取数量:

<% if user_signed_in? %>
  <%= current_order.order_items.size %>
<% else %>
  0
<% end %>

3. (可选)添加全局辅助方法

若多个页面需显示购物车数量,在ApplicationHelper中添加辅助方法:

module ApplicationHelper
  def cart_size
    return 0 unless user_signed_in?
    current_order.order_items.size
  end
end

视图中直接调用:

<%= cart_size %>

4. 全局化current_order方法

将current_order移至ApplicationController并设为辅助方法,确保所有控制器和视图都能调用:

class ApplicationController < ActionController::Base
  before_action :authenticate_user!, except: [:index, :show] # 按需调整

  def current_order
    return nil unless user_signed_in?
    order = Order.where(user_id: current_user.id, status: 'created').order(updated_at: :desc).last
    order || Order.create(user_id: current_user.id)
  end
  helper_method :current_order # 允许视图调用该方法
end

修改后,购物车数量将从数据库中用户的实时订单数据获取,无论登录状态如何变化,都能保持数据一致且持久化。

内容的提问来源于stack exchange,提问作者AndresM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 20:23:09