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

Rails 7.0.4中Turbo Stream无法更新yield块外的_header局部视图

解决Turbo Stream无法更新Header购物车数量的问题

核心问题

你在CartItemsController#destroy的Turbo Stream指令中,错误地将数值类型的购物车数量作为目标元素ID传入turbo_stream.update,导致Turbo无法找到对应的DOM元素进行更新。终端显示加载了局部视图,但实际没有匹配到可操作的元素,所以Header的数量指示器始终显示旧数据。

修复步骤

1. 修正Controller中的Turbo Stream目标ID

将更新目标改为Header中数量指示器的DOM元素ID(cart_quantity),直接传入最新计算的数量值:

# app/controllers/cart_items_controller.rb
def destroy
  authorize cart_item
  if cart_item.destroy
    if cart_item.cart.cart_item_ids.any?
      cart_sum
      cart_quantity = cart_item.cart.cart_items.count
      respond_to do |format|
        format.turbo_stream do
          render turbo_stream: [
            turbo_stream.remove(@cart_item),
            # 直接更新指定ID的DOM元素,传入最新数量
            turbo_stream.update('cart_quantity', cart_quantity),
            turbo_stream.update('cart_sum', partial: 'carts/cart_sum')
          ]
        end
        format.html { redirect_to cart_path(current_user.cart.id) }
      end
    else
      redirect_to cart_path(current_user.cart.id)
    end
  end
end

2. 优化购物车数量局部视图

修改_cart_quantity.html.erb,支持接收局部变量,避免依赖全局current_user的旧数据:

# app/views/carts/_cart_quantity.html.erb
<%= cart_quantity || (current_user.nil? ? '' : current_user.cart.cart_items.count) %>

3. 可选:更新整个Header(如果需要)

如果需要更新整个Header而非仅数量,先给Header容器添加ID:

# app/views/shared/_header.html.erb
<div class="header" id="site_header">
  <!-- 原有Header内容 -->
</div>

然后在Controller中更新这个容器:

turbo_stream.update('site_header', partial: 'shared/header', locals: { cart_quantity: cart_quantity })

4. 清理冗余代码

删除Controller中冗余的get_cart_quantity方法调用,直接使用已计算的cart_quantity变量即可。

验证

删除购物车商品后,终端会显示Turbo Stream正确发送了更新指令,Header中的购物车数量会实时更新,无需刷新页面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 23:45:32