While designing database structure, you may get to know that some tables are related to one another. For example in a blog application, a one country have many states and states have many cities. In a MySQL database tables, we add one table's id to another table or create pivot table to create relationship between tables.
Laravel provides eloquent relationship which provides powerful query builders. In Laravel, eloquent relationships are defined in model classes. Laravel eloquent provides easy ways to create common relationships:
In this article, we will learn how to create many to many eloquent relationship between two models. This is slightly complicated than one to one and one to many relationship. For example, One Role may have more than one Permission and same way, one Permission can be assigned to more than one Role.
In this example, we assume that you have created fresh Laravel application. We also assume that you have confiured database connection.
To create many to many relationship, we need three database tables: roles
, permissions
and permission_role
. The permission_role
table is created from the alphabetical order of the related model names and contains two fields: role_id
and permission_id
. The table is used as intermediate table between roles and permissions.
we need to create three migration table. Run the following three commands into Terminal to create migration classes at database/migrations
directory.
php artisan make:migration create_roles_table
php artisan make:migration create_permissions_table
php artisan make:migration create_permission_role_table
Below are the migration table fields for these table:
roles migration
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
permissions migration
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('permissions', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
permission_role migration
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('permission_role', function (Blueprint $table) {
$table->integer('role_id');
$table->integer('permission_id');
$table->timestamps();
});
}
Run the migrate command to create tables into database.
php artisan migrate
Laravel model located at app/Models
directory. Create model classes for these tables using following Artisan commands one by one into Terminal.
php artisan make:model Role
php artisan make:model Permission
Now, you need to create permissions method in the Role model that will return belongsToMany method of Illuminate\Database\Eloquent\Model
class.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
use HasFactory;
/**
* The roles that belong to the user.
*/
public function permissions()
{
return $this->belongsToMany(Permission::class);
}
}
The eloquent will automatically checks role_id and permission_id fields in the permission_role pivot table which relates to id field of both tables. You can also define pivot table into relationship method as second parameter.
return $this->belongsToMany(Permission::class, 'permission_roles');
To define reverse relationship, i.e., if you already have permission and you want to find all roles of the permission by relationship, you need to create roles method into Permission model.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Permission extends Model
{
use HasFactory;
/**
* The roles that belong to the permission.
*/
public function roles()
{
return $this->belongsToMany(Role::class);
}
}
Now, if your pivot table also have some extra fields which are required when you retrieve relationship data, then you need to specify them when defining the relationship:
return $this->belongsToMany(Role::class)->withPivot('is_active', 'created_at');
In routes/web.php
file, we have added new route for relationship testing.
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PermissionController;
Route::get('/permission', [PermissionController::class, 'index']);
As we have added route, also create PermissionController with following command.
php artisan make:controller PermissionController
Find all permissions for the specific role
Open the controller at app/Http/Controllers/PermissionController
and create index method.
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$permissions = Role::find(1)->permissions;
dd($permissions);
}
This will return all permissions of the the role with the id of 1. As all the relationship serve as query builder, you may also constraints in permissions() method.
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$permissions = User::find(1)->permissions()
->orderBy('created_at' 'desc')
->get();
dd($permissions);
}
Find all roles for the selected permission
Now suppose you want to find all the roles which are assigned the permission, i.e., reverse relationship, here is how to access user record.
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$roles = Permission::find(1)->roles;
dd($roles);
}
You can even eager load the relationship data while quaring parent model data using with() methdod.
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$roles = Role::with('permissions')->get();
foreach($roles as $role) {
echo($role->permissions);
}
}
I hope this will help you to understand many to many eloquent relationship.
Hi, My name is Harsukh Makwana. i have been work with many programming language like php, python, javascript, node, react, anguler, etc.. since last 5 year. if you have any issue or want me hire then contact me on [email protected]
How to create a query string from an array in PHP
When sending get request to third party...How to toggle text inside and element on click using jQuery
Use the jQuery text() method You can...How To Send email In NodeJs
Today, Laravelcode share with you how to...Get The Difference Between Two Date In Laravel Using jpmurray/laravel-countdown
Today, Laravelcode share with you how to...onClick event Handling in React with Example
In this tutorial, we are going to look a...