Seeding additional fields and timestamps within pivot table

Step 01: create fresh laravel project

composer create-project laravel/laravel advanced_pivot_table

Step 02: Setting Up scaffolding migration of Role with artisan command

php artisan make:model Role -m

Step 03: Setting up scaffolding migration of pivot table role_user with artisan command

php artisan make:migration create_role_user_table

Step 04: Setting up database and updating db config in .env file

DB_DATABASE= laravel_advanced_pivot_table

Step 05: Specifying migration definition in database\migrations\2023_01_03_135616_create_roles_table.php

public function up()
{
    Schema::create('roles', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->timestamps();
    });
}

Step 06: Specifying migration definition in database\migrations\2023_01_03_151002_create_role_user_table.php

public function up()
{
    Schema::create('role_user', function (Blueprint $table) {
        $table->foreignId('user_id')->constrained();
        $table->foreignId('role_id')->constrained();
    });
}

Step 07: Setting up User model in App\Models\User.php

class User extends Model
{

    public function roles()
    {
        return $this->belongsToMany(Role::class);
    }
    
}

Step 08: Seeding User, Role and Pivot table role_user in DatabaseSeeder.php

\App\Models\Role::create(['name' => 'Administrator']);
\App\Models\Role::create(['name' => 'Editor']);
\App\Models\Role::create(['name' => 'Author']);

$user = \App\Models\User::create([
								'name' => 'Administrator', 
								'email' => 'admin@admin.com', 
								'password' => bcrypt('password') 		
							]); 
							
$user->roles()->attach(1);

Step 09: Seeding with timestamps

Back in database\migrations\2023_01_03_151002_create_role_user_table.php adding changes like below

public function up()
{
	Schema::create('role_user', function (Blueprint $table) {        
		$table->foreignId('user_id')->constrained();
		$table->foreignId('role_id')->constrained();
		$table->timestamps();            
	});
}

But running artisan command php artisan migrate:fresh --seed timestamp fields of pivot table role_user will not be filled. Therefore, to save these we need make changes in model User.php like below adding withTimestamps() method for pivot table.

public function roles()
{
   return $this->belongsToMany(Role::class)->withTimestamps();
}

This time if we run the seed artisan command timestamp fields will get populated.

Step 10: Seeding additional fields for pivot table

If we want to add a field approved in pivot table role_user and seed with data we need to do following changes

Back in 2023_01_03_151002_create_role_user_table.php changing migration file like below

public function up()
{
	Schema::create('role_user', function (Blueprint $table) {        
		$table->foreignId('user_id')->constrained();
		$table->foreignId('role_id')->constrained();
		$table->boolean('approved')->default(0);
		$table->timestamps();            
	});
}

Back in DatabaseSeeder.php changing like below

$user->roles()->attach(1, ['approved' => 1]);
$user->roles()->attach(2);


Step 11:
Accessing pivot table fields

Back in User.php modal making changes like below

public function roles()
{
	return $this->belongsToMany(Role::class)->withTimestamps()->withPivot(['approved']);
}  

Then in blade file we can use like below


foreach( $user->roles as $role ) { 
	echo $role->name.'
'
; echo $role->pivot->created_at.'
'
; echo $role->pivot->approved; } ?>

Step 12: Lastly, Filtering on pivot table relation

In User.php model we need to add 

public function approvedRoles()
{
   return $this->belongsToMany(Role::class)->wherePivot('approved', 1);
} 
?>

Then in blade file we can use like below

foreach( $user->approvedRoles as $role ) { 
	echo $role->name.'\n'; 
} 

Related Posts