Many to many relationship( belongsToMany )

Belongs to many is a combination of belogsTo and hasMany. When a table one or more rows associated with another table one or more rows that called many to many relationship. In this example we will see a user associated with multiple roles and a role associated with multiple users.

If you have fresh laravel installed then you will find database/migrations/xxx_create_users_table. But we also need roles table and a pivot table.

php artisan make:migration create_roles_table –create --table=roles

Database/migrations/xxxx_create_roles_table.php

<?php

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

class CreateRolesTable extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('roles', function(Blueprint $table)
		{
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
		});
	}

	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
        Schema::drop('roles');
    }

}

In case of many to many relationship we also need a pivot table. This pivot table contains role_id and user_id columns which have reference of both table.  

php artisan make:migration create_user_role_pivot_table –create –table=user_role

Database/migrations/xxxx_create_user_role_pivot_table.php

<?php

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

class CreatePivotTableUserRole extends Migration {

	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('user_role', function(Blueprint $table)
		{
            $table->increments('id');
            $table->integer('user_id')->unsigned();
            $table->foreign('user_id')->references('id')->on('users');
            $table->integer('role_id')->unsigned();
            $table->foreign('role_id')->references('id')->on('roles');
        });
	}

	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
        Schema::drop('user_role');
	}

}
php artisan migrate

Now, We have users, roles and user_role tables. Let's move on further process like our role and user model.

php artisan make:model role

 

App/role.php

<?php namespace App;
use Illuminate\Database\Eloquent\Model;

class Role extends Model {
    protected $table='roles';
	
    public function users(){
        return $this->belongsToMany('App\User', 'user_role');
    }
}

App/user.php

<?php namespace App;
use Illuminate\Database\Eloquent\Model;

class Role extends Model {
    protected $table='users';
	
    public function roles(){
        return $this->belongsToMany('App\Role', 'user_role');
    }
}

 

App/Http/routes.php

<?php
// http://localhost/userAssociatedRole/john
Route::get('userAssociatedRole/{username}', function($username){
    // Looking for name = john according to above demo url from users table
    $user = App\User::where('name', $username)->with('roles')->first();
    return view('user', compact('user'));
});

// http://localhost/userAssociatedRole/administrator
Route::get('roleAssociatedUser/{rolename}', function($rolename){
    // Looking for name = administrator according to above demo url from roles table  
    $role = App\Role::where('name', $rolename)->with('users')->first();
    return view('role', compact('role'));
});

You may have noticed i used eager loading with() in both routes, It removes the N+1 query problem.   

resources/views/user.blade.php

Display user name with all associative roles

<h1>{!!$user->name!!} authorized for-</h1>
@foreach( $user->roles as $user->role)
   <h3>Role: {!! $user->role->name !!}</h3>
@endforeach

 

resources/views/role.blade.php

Display role name with all associative users

<h1>Users authorize for {!!$role->name!!}</h1>
@foreach( $role->users as $role->user)
    <h3>User: {!! $role->user->name !!}</h3>
@endforeach

 

Something to say? Tell us in comment section.