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

使用category_products中间表关联分类与产品,按分类取5个产品失败求助

问题分析

你的代码里在with('categoryProducts')的闭包中直接调用take(4),这会导致所有分类总共只返回4条categoryProducts记录,而不是每个分类返回对应数量的产品(你实际需要的是5条)。这是因为take()在预加载关联时是全局限制,而非针对每个父模型的关联限制。

解决方案

方法一:优化关联定义(推荐)

首先确保你的Category模型中定义了与Product的多对多关联(通过category_products中间表):

// Category.php
public function products()
{
    return $this->belongsToMany(Product::class, 'category_products');
}

然后定义一个专门用于获取Top5产品的关联:

// Category.php
public function topProducts()
{
    return $this->products()
        ->orderBy('sold', 'desc')
        ->take(5);
}

最后修改查询代码:

$query = $this->getQuery();
$query->where('parent_id', '0')
    ->with('topProducts')
    ->whereHas('products'); // 过滤掉没有产品的分类
return $query->get();

方法二:预加载时使用子查询(适配多关联层级场景)

如果必须保留categoryProducts关联(比如需要中间表的额外字段),可以用子查询来实现每个分类取5条关联记录:

$query = $this->getQuery();
$query->where('parent_id', '0')
    ->with(['categoryProducts' => function ($q) {
        $q->with('product')
            ->orderBy('sold', 'desc')
            // 子查询限制每个分类的关联数量
            ->whereIn('category_products.id', function ($sub) {
                $sub->select('id')
                    ->from('category_products')
                    ->whereColumn('category_id', 'categories.id')
                    ->orderBy('sold', 'desc')
                    ->take(5);
            });
    }])
    ->whereHas('categoryProducts');
return $query->get();

方法三:分批加载(适合小数据量场景)

如果数据量不大,也可以先获取分类,再逐个加载对应的关联产品,避免全局take()的问题:

$categories = $this->getQuery()
    ->where('parent_id', '0')
    ->whereHas('categoryProducts')
    ->get();

$categories->each(function ($category) {
    $category->load(['categoryProducts' => function ($q) {
        $q->with('product')
            ->orderBy('sold', 'desc')
            ->take(5);
    }]);
});

return $categories;

注意:方法三会产生N+1查询(N为分类数量),数据量大时不推荐使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 23:57:27