从父多对多关系获取所有子模型 Laravel Eloquent

Posted

技术标签:

【中文标题】从父多对多关系获取所有子模型 Laravel Eloquent【英文标题】:Get all child models from parent Many to Many relationship Laravel Eloquent 【发布时间】:2021-03-23 01:23:48 【问题描述】:

我正在使用 Laravel 5.8 构建电子商务网站,但遇到以下问题。我想从一个类别及其子类别中检索所有产品,但之后能够在我的代码中执行过滤查询。例如产品的价格限制和数量供应。

商店有类别,在同一张表中有子类别。 类别表(简体) - id|name|parent_id - 如果 parent_id != 0,则该类别被视为主类别的子类别。

产品可以属于多个类别,因此我使用的是多对多关系。 产品表(简体) - id|name... 产品类别表 - id|product_id|category_id

我的产品模型如下所示:

public function categories()

    return $this->belongsToMany(
        'App\CatalogCategory', 
        'catalog_product_categories', 
        'product_id', 
        'category_id'
    );

还有我的类别模型:

public function allProducts()

    return $this->belongsToMany(
        'App\CatalogProduct', 
        'catalog_product_categories', 
        'category_id', 
        'product_id'
    )
        ->where('is_active', 1)
        ->whereDate('active_from', '<=', Carbon::now('Europe/Sofia'))
        ->where(function ($query)
        
            $query->whereDate('active_to', '>=', Carbon::now('Europe/Sofia'))
                ->orWhereNull('active_to');
        )
        ->wherePivotIn('category_id', $this->allChildrenIds());;  

目前这样做,返回一个空集合:

$category = CatalogCategory::find(3);
dd($category->allProducts);

【问题讨论】:

定义的关系被命名为products,所以它应该被访问为$category-&gt;products;——不是allProducts不是吗 我的错,没有正确复制它。我已经编辑过了。 【参考方案1】:

好的,我猜问题是-&gt;wherePivotIn('category_id', $this-&gt;allChildrenIds())

您正在尝试获取某个类别的产品 - 对应的记录可以通过数据透视表中的一行来标识,该行具有该类别的 id 和其他各种 product_id。

但是 wherePivotIn 在$this-&gt;allChildrenIds() 中不包含当前类别的 id,因此不会返回任何记录。

定义不带 wherePivotIn 的关系

public function allProducts()

    return $this->belongsToMany(
        'App\CatalogProduct', 
        'catalog_product_categories', 
        'category_id', 
        'product_id'
    )
        ->where('is_active', 1)
        ->whereDate('active_from', '<=', Carbon::now('Europe/Sofia'))
        ->where(function ($query)
        
            $query->whereDate('active_to', '>=', Carbon::now('Europe/Sofia'))
                ->orWhereNull('active_to');
        );  

然后获取当前类别及其所有子类别的所有产品

$category = Category::with(['products', 'subcategories.products'])->get();

通过此查询,与子类别关联的产品将分别嵌套在每个子类别下。

【讨论】:

这行得通,但是有没有办法通过一些查询来获取一个集合中的所有产品?我需要能够查询产品的价格范围并获取计数聚合 在一个集合中获取所有产品的一种简单方法是进行两个查询:首先查询所有具有子类别的类别并提取 id。在第二个查询中使用这些 id 来获取 category_id 在 id 数组中的所有产品,然后您可以针对价格范围的其他 where 条件进行附加

以上是关于从父多对多关系获取所有子模型 Laravel Eloquent的主要内容,如果未能解决你的问题,请参考以下文章

如何在多对多关系 Laravel 中检索所有相关模型?

从laravel中的多对多关系中获取单列

laravel 模型关联之(多对多)

Laravel 多对多关系 - 检索模型

多对多到 MorphToMany 关系

Laravel5.1 模型 --多对多关系