Create a nested lists of categories in Laravel 5

2019-05-06 02:30发布

问题:

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 |                |
+-------------+------------------+------+-----+---------------------+----------------+

回答1:

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


回答2:

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


标签: php laravel-5