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

Laravel 7+AJAX购物车新增商品时foreach无法加载最新数据

搞定你的Laravel购物车AJAX渲染问题

嘿,兄弟,我一眼就看出问题出在哪了——你踩了Laravel Eloquent关联缓存的经典坑!

问题根源

当你第一次执行foreach ($order->orderItems as $key => $order_item)的时候,Laravel会自动查询数据库并把订单项的集合缓存到$order模型实例里。之后你创建了新的订单项,但再访问$order->orderItems时,它直接用的是之前缓存的旧数据,根本没去数据库查最新的内容,所以第一次添加新商品时渲染的HTML里没有这条新项。而第二次添加时,你是更新已有的订单项,缓存里本来就有这个条目,数量更新后能正常同步,所以就显示出来了。

解决方法(三种任选其一)

1. 单独重新加载orderItems关联

在创建新订单项之后,加一行代码强制重新从数据库加载订单项:

if ($bingo == false) {
    $new_item = new OrderItem();
    $new_item->order_id = $order_id;
    $new_item->product_id = $product_id;
    $new_item->save();
    // 关键:重新加载关联,拿到最新数据
    $order->load('orderItems');
}

2. 刷新整个Order模型

如果想让整个$order模型都同步最新数据,也可以用refresh()方法:

if ($bingo == false) {
    $new_item = new OrderItem();
    $new_item->order_id = $order_id;
    $new_item->product_id = $product_id;
    $new_item->save();
    // 刷新整个模型,所有关联都会重新加载
    $order->refresh();
}

3. 直接查询最新的订单项集合

另一种思路是绕过模型关联缓存,直接从数据库查询最新的订单项:

// 替换原来的foreach部分
// 直接查数据库,拿到最新的所有订单项
$orderItems = OrderItem::where('order_id', $order_id)->get();
$output = "";
foreach ($orderItems as $item) {
    // 原来的HTML拼接代码完全不变
}

修改后的完整控制器代码

这里用重新加载关联的方法给你贴出完整的修改版:

public function addItem($product_id, Request $request){
    $order_id = auth()->user()->waitingOrder->first()->id;
    $order = Order::find($order_id);
    $bingo = false;
    foreach ($order->orderItems as $key => $order_item) {
        if ($product_id == $order_item->product_id) {
            $order_item->quantity = $order_item->quantity + 1;
            $order_item->save();
            $bingo = true;
            break;
        }
    }
    if ($bingo == false) {
        $new_item = new OrderItem();
        $new_item->order_id = $order_id;
        $new_item->product_id = $product_id;
        $new_item->save();
        // 新增这行,刷新关联缓存
        $order->load('orderItems');
    }
    $output = "";
    foreach ($order->orderItems as $item) {
        $output .= '<tr>'.
        '<td align="left" width="15%">'.
        '<img style="height: 80px; width: 80px;" src="'. asset('img/products/' . $item->product->image) .'">'.
        '</td>'.
        '<td align="center" width="20%">'. $item->product->name . '</td>'.
        '<td>'. rupiah($item->product->price) . '</td>'.
        '<td width="14%">'.
        '<input type="number" class="form-control" name="quantity" value="'. $item->quantity .'" min="1" max="'. $item->product->stock .'">'.
        '</td>'.
        '<td>'. rupiah($item->product->price * $item->quantity) . '</td>'.
        '<td>'.
        '<a href="'. route('kasir.remove.item', $item->product->id ) .'" class="remove-btn">'.
        '<span class="icon_close"></span>'.
        '</a>'.
        '</td>'.
        '</tr>';
    }
    return response($output);
}

这样修改后,第一次添加新商品时,渲染HTML用的就是数据库里最新的订单项集合了,问题就能解决!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 14:27:38