Laravel使用withCount实现品牌、店铺、分类关联商品动态计数方案咨询
Laravel 场景化商品计数实现方案
一、补全缺失的模型关联
首先给Product模型新增和分类的多对多关联:
// App\Models\Product public function categories() { return $this->belongsToMany(Category::class, 'ec_product_category_product', 'product_id', 'category_id'); }
新增Category模型的商品关联:
// App\Models\Category public function products() { return $this->belongsToMany(Product::class, 'ec_product_category_product', 'category_id', 'product_id') ->where('is_variation', 0); }
原有Brand、Store模型的products关联保持不变即可。
二、封装动态筛选逻辑
利用Laravel withCount 支持闭包注入条件的特性,统一封装请求参数的筛选逻辑:
// 控制器中先获取请求筛选参数 $filters = request()->only(['brand_id', 'store_id', 'category_id']); // 生成通用的商品筛选闭包,三个查询场景复用 $productFilter = function ($query) use ($filters) { // 选中指定品牌时追加品牌筛选 if (isset($filters['brand_id'])) { $query->where('brand_id', $filters['brand_id']); } // 选中指定店铺时追加店铺筛选 if (isset($filters['store_id'])) { $query->where('store_id', $filters['store_id']); } // 选中指定分类时追加分类关联筛选 if (isset($filters['category_id'])) { $query->whereHas('categories', function ($q) use ($filters) { $q->where('category_id', $filters['category_id']); }); } };
三、分场景执行查询统计
所有场景复用上面的筛选闭包,自动匹配请求参数实现对应计数:
- 统计品牌列表对应商品数
$brandList = Brand::withCount(['products' => $productFilter])->get(); // 统计结果存储在 products_count 字段 - 统计店铺列表对应商品数
$storeList = Store::withCount(['products' => $productFilter])->get(); // 统计结果存储在 products_count 字段 - 统计分类列表对应商品数
$categoryList = Category::withCount(['products' => $productFilter])->get(); // 统计结果存储在 products_count 字段
方案优势
- 逻辑复用:三个场景共用同一套筛选规则,后续新增筛选条件只需要修改闭包即可
- 自动适配:支持同时传入多个筛选参数,自动叠加条件统计符合要求的商品数
- 原生ORM实现:不需要手写复杂SQL,兼容性和性能有保障
内容的提问来源于stack exchange,提问作者techieMad
相关产品推荐
相关产品推荐

