Create a nested lists of categories in Laravel 5

2019-05-06 02:26发布

Am fairly new to Laravel and am trying to create a tree-like categories structure for my app. This is the code have I used to far but still unable to achieve what I want. My controller:

public function index()
{
    $categories = Category::with('children')->get();

    return view('backend.categories.index')->with('categories', $categories);
}

My category model:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    protected $guarded = ['id'];

    public function parent()
    {
        return $this->belongsTo('App\Category', 'parent_id');
    }

    public function children()
    {
        return $this->hasMany('App\Category', 'parent_id');
    }
}

My view:

<table class="table table-bordered table-hover">
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Description</th>
                        <th>Slug</th>
                        <th>Action</th>
                    </tr>
                </thead>
                <tbody>
                @foreach ($categories as $category)
                    {{--@foreach ($category->children as $children)--}}
                    <tr>
                        <td>{{ $category->name }}</td>
                        <td>{{ $category->description }}</td>
                        <td>{{ $category->slug }}</td>
                        <td><a class="edit" href="{!! action('Admin\CategoriesController@edit', $category->id) !!}" title="Edit"><i class="fa fa-pencil-square-o"></a></i> <a class="delete" href="{!! action('Admin\CategoriesController@destroy', $category->id) !!}" title="Are you sure you want to delete?"><i class="fa fa-trash-o"></i></a></td>
                        @foreach ($category->children as $children)
                            <tr>
                                <td>{{ $children->name }}</td>
                                <td>{{ $children->description }}</td>
                                <td>{{ $children->slug }}</td>
                                <td></td>
                            </tr>
                        @endforeach
                    </tr>
                </tbody>
                    {{--@endforeach--}}
                @endforeach
            </table>

Am trying to produce a structure like below:

  • Fashion Accessories
    • Bags
    • Cloths
  • Mobile Phones
    • Tablets
    • Smartphones

EDIT There is my database structure:

+-------------+------------------+------+-----+---------------------+----------------+
| Field       | Type             | Null | Key | Default             | Extra          |
+-------------+------------------+------+-----+---------------------+----------------+
| id          | int(10) unsigned | NO   | PRI | NULL                | auto_increment |
| name        | varchar(255)     | NO   |     | NULL                |                |
| slug        | varchar(255)     | NO   |     | NULL                |                |
| parent_id   | int(11)          | YES  |     | NULL                |                |
| description | text             | NO   |     | NULL                |                |
| created_at  | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
| updated_at  | timestamp        | NO   |     | 0000-00-00 00:00:00 |                |
+-------------+------------------+------+-----+---------------------+----------------+

标签: php laravel-5
2条回答
做自己的国王
2楼-- · 2019-05-06 02:39

You are currently loading all categories (including the child ones) and then looping through them. You only want to load the root categories (categories without parent). To do this, change your controller method to only load categories where the parent_id is null.

$categories = Category::whereNull('parent_id')->with('children')->get();
查看更多
祖国的老花朵
3楼-- · 2019-05-06 02:45

Probably in model you need to change inorder to refer to children model:

public function children()
    {
        return $this->hasMany('App\Children', 'parent_id');
    }

Model for category:

class Category extends Model
{
    protected $guarded = ['id'];
    protected $fillable = array('name','description','slug','created_at','updated_at');

    public function children()
    {
        return $this->hasMany('App\Children', 'parent_id');
    }
}

Model for childrens:

class Children extends Model {
     protected $table = 'children';
     protected $fillable = array('name','description','parent_id','created_at','updated_at');
}

In controller get categories with children like this:

$categories = Category::with(['children'])->get();

and correct the tags -- <i class="fa fa-pencil-square-o"></i></a>

then in the view:

@foreach ($categories as $category)              
       <ul>
           <li>{{ $category->name }}</li>
           <li>{{ $category->description }}</li>
           <li>{{ $category->slug }}</li>
           <li><a class="edit" href="{!! action('Admin\CategoriesController@edit', $category->id) !!}" title="Edit"><i class="fa fa-pencil-square-o"></i></a> <a class="delete" href="{!! action('Admin\CategoriesController@destroy', $category->id) !!}" title="Are you sure you want to delete?"><i class="fa fa-trash-o"></i></a></li>


               @foreach ($category->children as $children)
                  <ul>
                    <li>{{ $children->name }}</li>
                    <li>{{ $children->description }}</li>
                    <li>{{ $children->slug }}</li>
                    <li></li>
                  </ul>
               @endforeach

       </ul>
@endforeach
查看更多
登录 后发表回答