Laravel 8使用Query Builder按分类循环展示商品仅显示最后分类如何解决
问题原因
- 控制器内
$data变量在循环分类时被反复覆盖,循环结束后仅保留最后一个分类的产品数据 - 缩略图仅查询了最后一个分类下第一个产品的对应数据,没有和所有产品做关联
- Blade模板循环逻辑错误,
@foreach闭合错误使用了@endif,且没有建立分类、产品、缩略图的层级对应关系
修复方案(查询构造器版本)
控制器代码修改
$categories = DB::table('tbl_categories') ->orderBy('name') ->get() ->map(function ($category) { // 挂载当前分类下的所有启用商品 $category->products = DB::table('tbl_product') ->where('status', 'Enable') ->where('category_id', $category->id) ->get() ->map(function ($product) { // 挂载单个商品对应的缩略图,单个商品多图就把first改为get $product->thumbnail = DB::table('tbl_thumbnails') ->where('product_id', $product->id) ->first(); return $product; }); return $category; }); return view('/products', ['categories' => $categories]);
Blade模板代码修改
@foreach($categories as $discover_category) <div> {{-- 分类名称 --}} <p>{{ $discover_category->name }}</p> @foreach($discover_category->products as $product) <div style="padding-left: 2em;"> {{-- 商品名称 --}} <span>{{ $product->name }}</span> {{-- 商品缩略图,字段名根据自己表的实际字段调整 --}} @if(!empty($product->thumbnail)) <img src="{{ $product->thumbnail->src }}" alt="{{ $product->name }}"> @endif </div> @endforeach </div> @endforeach
更优方案(Eloquent关联版本,推荐)
Laravel的ORM关联可以避免N+1查询问题,性能更高,代码更简洁:
- 先创建对应模型并定义关联
Category.php模型中添加关联方法:
public function products() { return $this->hasMany(Product::class, 'category_id')->where('status', 'Enable'); }
Product.php模型中添加关联方法:
public function thumbnail() { return $this->hasOne(Thumbnail::class, 'product_id'); // 单个商品多图就改为return $this->hasMany(Thumbnail::class, 'product_id'); }
- 控制器代码简化为:
// 预加载关联数据,仅执行3次查询 $categories = \App\Models\Category::with('products.thumbnail') ->orderBy('name') ->get(); return view('/products', compact('categories'));
Blade模板代码和上面的修复版完全一致。
内容的提问来源于stack exchange,提问作者Rian
相关产品推荐
相关产品推荐

