Laravel Eloquent HasMany Recursive Relationship with Subitems

Today I’m going to show how to view items and deep level sub-items. Let’s get started:

Table of Contents

  1. Database Migration
  2. Eloquent Model and Relationships
  3. Modify Controller and Define Route
  4. Create Views

Database Migration

Create a model, migrations and controller using this command:

php artisan make:model Item -mc

Open the newly created migration file from database/migrations folder and update up() method:

public function up()
    Schema::create('items', function (Blueprint $table) {

Now migrate the database:

php artisan migrate

Eloquent Model and Relationships

We’re going to add two relations in app/Item.php model. One for displaying level one items and another one for showing recursive items:

class Item extends Model
    // return one level of child items
    public function items()
        return $this->hasMany(Item::class, 'parent_id');

    // recursive relationship
    public function childItems()
        return $this->hasMany(Item::class, 'parent_id')->with('items');

Modify Controller and Define Route

Open ItemController from app\Http\Controllers and add the index() method:


namespace App\Http\Controllers;

use App\Item;
use Illuminate\Http\Request;

class ItemController extends Controller
    public function index() {
        $items = Item::whereNull('parent_id')

        return view('items', compact('items'));

Now define a route in routes/web.php for the index() method:

Route::get('items', 'ItemController@index');

Create Views

Go to resources/views folder and create 2 files named items.blade.php and sub_items.blade.php. Then paste these codes:

    @if(count($items) > 0)
        @foreach ($items as $item)
            <li>{{ $item->name }}</li>
                    @foreach ($item->childItems as $childItems)
                        @include('sub_items', ['sub_items' => $childItems])
<li>{{ $sub_items->name }}</li>
@if ($sub_items->items)
        @if(count($sub_items->items) > 0)
            @foreach ($sub_items->items as $childItems)
                @include('sub_items', ['sub_items' => $childItems])

Now insert some data into items tables and run the project. Then visit http://localhost:8000/items route to see the output. Here’s my one:

That’s it. Thanks for reading.

Software Engineer | Ethical Hacker & Cybersecurity...

Md Obydullah is a software engineer and full stack developer specialist at Laravel, Django, Vue.js, Node.js, Android, Linux Server, and Ethichal Hacking.