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])
- Junior Manager (User ID: 2)
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