Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a nested lists of categories in Laravel 5

Tags:

php

laravel-5

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 |                |
+-------------+------------------+------+-----+---------------------+----------------+
like image 799
ammezie Avatar asked Oct 19 '22 04:10

ammezie


1 Answers

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();
like image 160
darthmaim Avatar answered Oct 30 '22 16:10

darthmaim