Home > Software design >  How to use a boot() in laravel model?
How to use a boot() in laravel model?

Time:10-15

I have two models and migration tables named as users and roles (for both migrations and models names).

This is the first time I am using boot(). I have one doubt: if the user is successfully registered then his role should be stored automatically in the roles table as admin, for that please help me I am trying some ways it's not working.

User.php

public static function boot()
{
    parent::boot();
    Static::updating(function (){});
    // Here I am unable to figure out how to pass roles model or migration take data and how to update the values
}

create_roles_table.php

$table->string('role');
$table->unsignedInteger('user_id');
$table->foriegn('user_id')->references ('id')->on('users');

CodePudding user response:

Many users can be 'admin', yes? Then the roles table should have the following structure.

// create_roles_table
$table->id();
$table->string('role'); // Admin, Manager, etc
$table->timestamps();

If an user can only have one role, then the users table should have a foreign key to the roles table.

// create_users_table
$table->id();
// other fields
$table->foreignId('role_id')->constrained('roles', 'id'); // equivalent to $table->unsignedBigInteger('role_id'); $table->foreign('role_id')->references('id')->on('roles');

When an user is registered, laravel fires the event Illuminate\Auth\Events\Registered.

You can listen to it in your App/Providers/EventServiceProvider class.

use Illuminate\Auth\Events\Registered;
use Illuminate\Support\Facades\Event;

class EventServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // Will fire every time an User registers
        Event::listen(function (Registered $event) {
            $event->user->forceFill(['role_id' => ADMIN_ROLE_ID])->save();
        });
    }
}

If you want to use the User Model's events instead, it should look like this:

class User extends Model
{
    public static function boot()
    {
        parent::boot();
        // Will fire everytime an User is created
        static::creating(function (User $user) {
            $user->forceFill(['role_id' => ADMIN_ROLE_ID])->save();
        });
    }
}

or using booted() instead

class User extends Model
{
    public static function booted()
    {
        // Will fire every time an User is created
        static::creating(function ($user) {
            $user->forceFill(['role_id' => ADMIN_ROLE_ID])->save();
        });
    }
}

If an user can have many roles, a separate migration is needed. role_id no longer needs to be on the users table.

// create_role_user_table
$table->id()
$table->foreignId('role_id')->constrained('roles', 'id');
$table->foreignId('user_id')->constrained('users', 'id');

Then you need to define a relationship in both User and Role models

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

As for updating the role when creating/registering an user an user, replace

user->forceFill(['role_id' => ADMIN_ROLE_ID])->save()

by

user->roles()->attach(ADMIN_ROLE_ID);
  • Related