Complete website in Rs. 5,000 with Free Hosting & Domain. Offer ends in  00:00:00
Back to Blog

How to Create a Many-to-Many Hierarchical Relationship in Laravel

Learn how to model complex hierarchical relationships in Laravel using a many-to-many approach. Follow our step-by-step guide with code examples to manage nested user roles effectively.

Jul 7, 2024 Updated: Jul 7, 2024

In many organizational structures, employees can have multiple managers, and managers can oversee multiple employees. Modeling this kind of hierarchical relationship in Laravel requires a many-to-many relationship. This guide will show you how to set up and use a self-referencing many-to-many relationship in Laravel.

Step 1: Create the Pivot Table

First, you need a pivot table to link users with their parents. This table will hold the relationships between users and their multiple parents.

Create a migration for the pivot table:

php artisan make:migration create_user_user_table --create=user_user

Update the migration file to define the pivot table:

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUserUserTable extends Migration
{
    public function up()
    {
        Schema::create('user_user', function (Blueprint $table) {
            $table->id(); // you can remove this if you don't want primary keys
            $table->unsignedBigInteger('user_id');
            $table->unsignedBigInteger('parent_id');

            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            $table->foreign('parent_id')->references('id')->on('users')->onDelete('cascade');
        });
    }

    public function down()
    {
        Schema::dropIfExists('user_user');
    }
}

Run the migration:

php artisan migrate

Step 2: Define the Many-to-Many Relationship in the User Model

Update the User model to define the many-to-many relationships. You’ll define a parents relationship to get the parent users and a children relationship to get the users that have the current user as their parent.

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class User extends Authenticatable
{
    // Define the parents relationship
    public function parents(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'user_user', 'user_id', 'parent_id');
    }

    // Define the children relationship
    public function children(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'user_user', 'parent_id', 'user_id');
    }
}

Step 3: Using the Relationships

With these relationships defined, you can easily access the parents and children of a user. Here’s an example of how to use these relationships:

// Get a user
$user = User::find(1);

// Get the parents of the user
$parents = $user->parents;

// Get the children of the user
$children = $user->children;

// Attach a parent to a user
$user->parents()->attach($parentUserId);

// Detach a parent from a user
$user->parents()->detach($parentUserId);

// Sync parents of a user (replaces existing parents)
$user->parents()->sync([$parentUserId1, $parentUserId2]);

Step 4: Example Data Structure

Assuming you have a hierarchy where an employee can have multiple HR managers as parents:

  • Manager (User ID: 1)
    • Junior Manager (User ID: 2)
      • Employee 1 (User ID: 3, parents: [2, 5])
      • Trainee (User ID: 4, parents: [2])
    • HR (User ID: 5)
      • Employee 1 (User ID: 3, parents: [2, 5])
      • Employee 2 (User ID: 6, parents: [5])

You can create these users and set their parent relationships appropriately:

$manager = User::create(['name' => 'Manager']);
$juniorManager = User::create(['name' => 'Junior Manager']);
$employee1 = User::create(['name' => 'Employee 1']);
$trainee = User::create(['name' => 'Trainee']);
$hr = User::create(['name' => 'HR']);
$employee2 = User::create(['name' => 'Employee 2']);

// Set relationships
$manager->children()->attach([$juniorManager->id, $hr->id]);
$juniorManager->children()->attach([$employee1->id, $trainee->id]);
$hr->children()->attach([$employee1->id, $employee2->id]);

$employee1->parents()->attach([$juniorManager->id, $hr->id]);
$employee2->parents()->attach($hr->id);
$trainee->parents()->attach($juniorManager->id);

// Paginate the children
$childrens = $manager->children()->paginate(10); // Adjust the number of items per page
// show pagination links in blade file
$children->links();

Conclusion

By using a pivot table and defining many-to-many relationships in the User model, you can create a hierarchical structure where a user can have multiple parents. This setup is flexible and can be used to model complex organizational structures effectively. Implementing such relationships in Laravel enhances the ability to manage nested user roles and relationships efficiently

Contact

Got A Question For Us?

Feel free to ask anything directly on call or fill the form and we will contact back within few hours.