Laravel 从父类别及其所有子类别中获取所有产品

我正在尝试从一个类别及其所有子类别中检索产品。


这是我的categories桌子:


| id    | parent_id     | name          |

|----   |-----------    |-------------  |

| 1     | NULL          | Electronics   |

| 2     | 1             | Computers     |

| 3     | 2             | Accessories   |

| 4     | 3             | Keyboards     |

这是我的产品表:


| id    | category_id   | name          |

|----   |-------------  |-----------    |

| 1     | 2             | Product 1     |

| 2     | 3             | Product 2     |

| 3     | 4             | Product 3     |

假设我在Computers类别页面中,我想显示此表中的产品以及所有产品。


所以它应该首先从Computersand Accessoriesand also获取产品Keyboards。


这是我的类别模型:


public function parent() {

    return $this->belongsTo(Category::class, 'parent_id');

}


public function childs() {

    return $this->hasMany(Category::class, 'parent_id');

}


public function products() {

    return $this->hasManyThrough(Product::class, Category::class, 'parent_id', 'category_id', 'id');

}

产品型号:


public function categories() {

    return $this->belongsTo(Category::class, 'category_id');

}

查询:


Category::with(['products', 'childs.products'])->where('id', $category->id)->get();

返回:


{

    "id":11,

    "parent_id":4,

    "name":"Computers",

    "products":[

        {

            "id":2,

            "category_id":12,

            "title":"Product 1",

            "laravel_through_key":11

        }

    ],

    "childs":[

        {

            "id":12,

            "parent_id":11,

            "name":"Accessories",

            "products":[

                {

                    "id":1,

                    "category_id":13,

                    "user_id":1,

                    "title":"Product 2",

                    "laravel_through_key":12

                }

            ]

        }

    ]

}

上面,它正在转义最后一个子类别Keyboards。


我曾尝试使用hasManyThrough关系,但我只得到了产品Computers,Accessories但没有达到Keyboards。


因此,如果我在一个类别中,我想从该类别树中获取所有产品。即使一个子类别有子类别。


我怎样才能做到这一点?


翻阅古今
浏览 241回答 4
4回答

郎朗坤

您可以通过以下方式修复它:建立递归关系:(请在此处参考 Alex Harris 的回答)// recursive, loads all descendants// App\Categorypublic function childrenRecursive(){   return $this->childs()->with('childrenRecursive');}$data = Category::with(['products', 'childrenRecursive', 'childrenRecursive.products'])->where('id', 2)->get()->toArray();#Edit:提取产品列表在控制器中定义Flatten laravel 递归关系集合(树集合)函数public function flatten($array){        $flatArray = [];        if (!is_array($array)) {            $array = (array)$array;        }        foreach($array as $key => $value) {            if (is_array($value) || is_object($value)) {                $flatArray = array_merge($flatArray, $this->flatten($value));            } else {                $flatArray[0][$key] = $value;            }        }        return $flatArray;}然后为了只有产品项目$data = Category::with(['products', 'childrenRecursive', 'childrenRecursive.products'])->where('id', 2)->get()->toArray();$flatten = $this->flatten($data);foreach ($flatten as $key => $fl) {    // eliminate categories from $flatten array    if (!array_key_exists('category_id', $fl)) {        unset($flatten[$key]);    }}$product = array_values($flatten);

慕神8447489

一种选择是使用类似laravel-adjacency-list 的东西。这将允许您使用CTE递归加载关系。以下是设置您的步骤(在撰写本文时)跑composer require staudenmeir/laravel-adjacency-list:"^1.0"将HasRecursiveRelationships特征添加到您的Category模型中:use Staudenmeir\LaravelAdjacencyList\Eloquent\HasRecursiveRelationships;class Category extends Model{    use HasRecursiveRelationships;    ...}将您的查询更改为:Category::with('descendants.products')->where('id', $id)->first(); //$id being the id of the parent category you want to get.如果您只想获取某个类别中/下的产品,您可以执行以下操作:Product::whereHas('category', function ($query) use ($category) {    $query->whereIn('categories.id', $category->descendantsAndSelf()->select('id')->getQuery());})->get();有关如何使用的更多信息,laravel-adjacency-list请参阅文档。

尚方宝剑之说

$categories  = Category::whereParentId(null)->with('children.children.children')->get();并查看您可以使用 foreach 循环显示项目

www说

如果你使用 ORM 雄辩的关系public function categoriesProduct(ProductCategory $category){     $categories = ProductCategory::where('parent_id', $category->id)                                  ->orWhere('id', $category->id)                                  ->latest()                                  ->get();     return view('categoryProduct', compact('categories', 'category'));}
打开App,查看更多内容
随时随地看视频慕课网APP