Laravel 在同一个表中返回父母的孩子

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32122849/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 12:13:44  来源:igfitidea点击:

Laravel returning children of parents in same table

phplaraveleloquentbladelaravel-5.1

提问by Randy Rankin

Using Laravel 5.1, I am trying to create a menu list from a MySQL categories table. My service provider returns data, but I don't understand how to create the child categories in a foreach loop. When I perform the loop, only the last row of the child query is returned. Any guidance would be appreciated.

使用 Laravel 5.1,我试图从 MySQL 类别表创建菜单列表。我的服务提供者返回数据,但我不明白如何在 foreach 循环中创建子类别。当我执行循环时,只返回子查询的最后一行。任何指导将不胜感激。

categories Table

类别表

id  | cat_name      | cat_parent_id
--- | --------------| ------------- 
1   | Parent Cat 1  | NULL 
2   | Parent Cat 2  | NULL 
3   | Child Cat 1   | 2 
4   | Child Cat 2   | 2 
5   | Parent Cat 3  | NULL 
6   | Child Cat 3   | 5

Desired Result

预期结果

Parent Cat 1
Parent Cat 2
    Child Cat 1
    Child Cat 2
Parent Cat 3
    Child Cat 3

viewComposerServiceProvider.php

viewComposerServiceProvider.php

public function boot()
{
       $this->composeTopCategoryNavigation();
       $this->composeSubCategoryNavigation();
}

private function composeTopCategoryNavigation()
{
    view()->composer('partials.header', function($view)
        {
            $view->with('top_cats', Category::whereNull('cat_parent_id')->orderBy('cat_name', 'asc')->get());
        });
}

private function composeSubCategoryNavigation()
{
        view()->composer('partials.header', function($view)
        {
            $view->with('sub_cats', Category::whereNotNull('cat_parent_id')->orderBy('cat_name', 'asc')->get());
        });
}

header view

标题视图

<ul>
@foreach ($top_cats as $top_cat)
  <?php $top_cat_slug = str_slug( $top_cat->cat_name, "-"); ?>
  <li>{{ $top_cat->cat_name }}
    @foreach ($sub_cats as $sub_cat)
            @if ( $sub_cat->cat_parent_id === $top_cat->id )
                <ul>
                  <li{{ $sub_cat->cat_name }}</li>
                </ul>
                @endif
        @endforeach
   </li>
@endforeach
</ul>

回答by jedrzej.kurylo

First of all, what you are doing is inefficient. Your view iterates through all subcategories for every parent category. If you defined relations properly and made use of Eloquent's eager loading, you could fetch and access child categories in easier way.

首先,你正在做的事情效率低下。您的视图遍历每个父类别的所有子类别。如果您正确定义了关系并使用了 Eloquent 的预先加载,您可以更轻松地获取和访问子类别。

Start with defining relations:

从定义关系开始:

class Category extends Model {
  //each category might have one parent
  public function parent() {
    return $this->belongsToOne(static::class, 'cat_parent_id');
  }

  //each category might have multiple children
  public function children() {
    return $this->hasMany(static::class, 'cat_parent_id')->orderBy('cat_name', 'asc');
  }
}

Once you have the relations defined properly, you can fetch whole category tree like below:

一旦正确定义了关系,就可以获取整个类别树,如下所示:

view()->composer('partials.header', function($view) {
  $view->with('categories', Category::with('children')->whereNull('cat_parent_id')->orderBy('cat_name', 'asc')->get());
});

The second composer won't be needed, as parent categories already contain children.

不需要第二个作曲家,因为父类别已经包含子类别。

Now, you only need to display the categories in your view:

现在,您只需要在视图中显示类别:

<ul>
  @foreach ($categories as $parent)
    <li>{{ $parent->cat_name }}
      @if ($parent->children->count())
        <ul>
          @foreach ($parent->children as $child)
            <li>{{ $child->cat_name }}</li>
          @endforeach
        </ul>
      @endif
    </li>
  @endforeach
</ul>

回答by KrisTemmerman

I've found the solution myself. I have to iterate through the results to get access to the member variable.

我自己找到了解决方案。我必须遍历结果才能访问成员变量。

@foreach($locations as $location)
            <tr>
                <td>
                    {{$location->location_id}}
                </td>
                <td>
                    @foreach($location->members as $member)
                        {{$member->first_name}}
                    @endforeach
                </td>
                <td>

                </td>
            </tr>
        @endforeach