如何使用laravel雄辩地优化循环查询

时间:2019-02-04 11:44:50

标签: php laravel eloquent

我正在尝试从数据库中以“树视图”获取类别,子类别和产品。 我是laravel的新手,我不知道如何使用雄辩的方法更好地编写此动作。 我有2张桌子:产品和类别 每个产品都有category_id,它是类别表的外键

这是我的代码:

    $categories = Category::with('products')->where('id', $category->id)->get()->toArray();
    foreach ($categories as $key => $value) {

        $categories[$key]['children'] = Category::with('products')->where('parent_id', $value['id'])->get()->toArray();
    }

这是我的结果,很好

“结果”:[

    {
        "id": 2,
        "name": "Root 2",
        "parent_id": null,
        "products": [],
        "children": [
            {
                "id": 4,
                "name": "First child of Root 2",
                "parent_id": 2,
                "products": [
                    {
                        "id": 5,
                        "category_id": 4,
                        "name": "مهسا واثقی",
                        "description": "Aut eum et rerum dolorum blanditiis et itaque ipsum. Reiciendis consectetur magni est veritatis qui. Eos veniam quo aspernatur exercitationem vel incidunt. Rem aut sunt ab exercitationem.",
                        "price": "58.00",
                        "type": "video",
                        "disabled": 0,
                        "created_at": "2019-02-03 22:38:37",
                        "updated_at": "2019-02-03 22:38:37"
                    },
                ]
            },
            {
                "id": 5,
                "name": "Second child of Root 2",
                "parent_id": 2,
                "products": []
            },
            {
                "id": 6,
                "name": "Third child of Root 2",
                "parent_id": 2,
                "products": []
            }
        ]
    }
],

3 个答案:

答案 0 :(得分:1)

您可以使用“ whereIn”代替循环查询。

$categories = Category::with('products')->where('id', $category->id)->get()->toArray();
$parentCategory = $categories->pluck('id');
$categoriesObject = Category::with('products')->whereIn('parent_id', $parentCategory)->get()->toArray();
foreach($categoriesObject as $key => $value){
 $childObject[$value->paernt_id][] = $value;
}
foreach($categories as $key => $value){
  $categories[$key]['child'] = isset($childObject[$value->id]) ? $childObject[$value->id] : [];
}

答案 1 :(得分:1)

您可以尝试使用递归关系,就像这样:

public function childCategoriesRecursive()
{
    return $this->hasMany(Category::class, 'id', 'parent_id')->with('childCategoriesRecursive');
}

加载此新关系时,Laravel将自动选择所有类别层次结构。因此,您的代码应类似于:

    $categories = Category::with(['childCategoriesRecursive', 'products', 'childCategoriesRecursive.products'])->where('id', $category->id)->get()->toArray();

现在,无需循环所有类别。

希望这会有所帮助!

答案 2 :(得分:0)

您可以通过以下方式使用递归功能

$categories = Category::with('products')->where('id', $category->id)->get()->toArray();

$categoriesWithChild = $this->GenerateCategoryArray($categories);
dd($categoriesWithChild);

在您的控制器中添加此功能:

function GenerateCategoryArray($arr, $parent = null)
{
    $pages = Array();
    foreach($arr as $page)
    {
       if($page['parent_id'] == $parent)
       {
           $page['child'] = isset($page['child']) ? $page['child'] : $this->GenerateCategoryArray($arr, $page['id']);
           $pages[] = $page;
        }
     }
      return $pages;
}