<?phpuse Illuminate\Support\Facades\Route;use App\Http\Controllers\TestController;/*|--------------------------------------------------------------------------| Web Routes|--------------------------------------------------------------------------|| Here is where you can register web routes for your application. These| routes are loaded by the RouteServiceProvider within a group which| contains the "web" middleware group. Now create something great!|*/Route::get('/test/{id}',[TestController::class,'index']);Route::get('/test2/{id}',[TestController::class,'index2']);Route::get('/create/{id}',[TestController::class,'create']);Route::get('/create2/{id}',[TestController::class,'create2']);
Laravel Many-to-many eloquent relationships are a little bit more complicated than hasOne and hasMany relationships. An example of many to many relationships is a user with may have multiple roles, where the role are also connected with multiple users. We can define many to many relationships by using belongToMany() helper with a pivot table.
So in this tutorial, you are going to learn how to create many-to-many relationships with migration with a foreign key schema for one to many relationships, use sync with a pivot table, create records, attach records, get all records, delete, update, where condition and everything related to many to many relationship.
laravel-9-many-to-many-relationship
Table Structure Of Many to Many
To define belongsToMany() relationship, three database tables are needed: users, roles, and role_user. The role_user table is called pivot table and derived from the alphabetical order of the related model names and contains user_id and role_id columns. This table will be used as an intermediate table linking the users and roles.
MakefileCopy
Defining Many to Many Relationship
Many-to-many relationships can be defined by writing a method that returns the result of the belongsToMany method. So we can create a many to many relationship with roles for a user like:
app/Models/User.php
PHPCopy
Now define the same relationship in the Role model:
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\User;
use App\Models\Role;
use App\Models\RoleUser;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
User::factory(10)->create();
Role::factory(6)->create();
RoleUser::factory(20)->create();
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments("id");
$table->string('name');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateRolesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->increments("id");
$table->string('name');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('roles');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateRoleUserTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('role_user', function (Blueprint $table) {
$table->integer("user_id");
$table->integer("role_id");
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('role_user');
}
}
<?php
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class UserFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = User::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'name' => $this->faker->name()
];
}
}
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use App\Models\RoleUser;
class RoleUserFactory extends Factory
{
protected $model = RoleUser::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
"user_id" => $this->faker->numberBetween(1, 10),
"role_id" => $this->faker->numberBetween(1, 6)
];
}
}
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use App\Models\Role;
class RoleFactory extends Factory
{
protected $model = Role::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
"name" => $this->faker->firstName()
];
}
}
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasFactory;
public $timestamps = false;
protected $fillable = [
'name'
];
/**
* The roles that belong to the user.
*/
public function roles()
{
return $this->belongsToMany(Role::class, 'role_user');
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class RoleUser extends Model
{
use HasFactory;
protected $table = 'role_user';
public $timestamps = false;
protected $fillable = [
'user_id',
'role_id'
];
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
use HasFactory;
public $timestamps = false;
protected $fillable = [
'name'
];
/**
* The roles that belong to the user.
*/
/**
* The users that belong to the role.
*/
public function users()
{
return $this->belongsToMany(User::class, 'role_user');
}
}
users
id - integer
name - string
roles
id - integer
name - string
role_user
user_id - integer
role_id - integer
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The roles that belong to the user.
*/
public function roles()
{
return $this->belongsToMany(Role::class, 'role_user');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
/**
* The users that belong to the role.
*/
public function users()
{
return $this->belongsToMany(User::class, 'role_user');
}
}
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
class TestController extends Controller
{
public function index($id)
{
$user = User::find($id);
foreach ($user->roles as $role) {
//
}
}
}
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class TestController extends Controller
{
public function index($id)
{
$user = User::find($id);
$roleIds = [1, 2];
$user->roles()->attach($roleIds);
}
}
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class TestController extends Controller
{
public function index($id)
{
$user = User::find($id);
$roleIds = [1, 2];
$user->roles()->sync($roleIds);
}
}