为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

PHP
翻阅古今 2022-07-22 19:27:23
我正在尝试从一个类别及其所有子类别中检索产品。这是我的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。因此,如果我在一个类别中,我想从该类别树中获取所有产品。即使一个子类别有子类别。我怎样才能做到这一点?
查看完整描述

4 回答

?
郎朗坤

TA贡献1921条经验 获得超9个赞

您可以通过以下方式修复它:


建立递归关系:(请在此处参考 Alex Harris 的回答)


// recursive, loads all descendants

// App\Category

public 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);


查看完整回答
反对 回复 2022-07-22
?
慕神8447489

TA贡献1780条经验 获得超1个赞

一种选择是使用类似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请参阅文档。


查看完整回答
反对 回复 2022-07-22
?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

$categories  = Category::whereParentId(null)->with('children.children.children')->get();

并查看您可以使用 foreach 循环显示项目


查看完整回答
反对 回复 2022-07-22
?
www说

TA贡献1775条经验 获得超8个赞

如果你使用 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'));

}


查看完整回答
反对 回复 2022-07-22
  • 4 回答
  • 0 关注
  • 240 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号