0

I'm working with Laravel 5.6 and Spatie laravel-permission and I want to modify the model_has_roles so it can have an extra field named code.

Now, i did that thing by modifying the migrations the library provides via the next command:

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="migrations"

This library provides a useful command:

$user->assignRole($role);

That lets me assign a role to an user within a single line of code. My problem is that, using this command will throw an error because i can't leave the code field empty. Either way, i can't do something like this:

$user->assignRole($role, ['code' => '0001']);

Because it will say that 0001 is not a role. Basically, it asumes that i'm trying to assign TWO different roles to the user: $role and 0001 while actually i'm trying to assign a single role: $role with an extra parameter for the table model_has_roles.

Is there a way to archieve such a thing? I thought that maybe i could modify the logic behind the assignRole method but i don't know how to extend/edit the library methods.

apokryfos
  • 38,771
  • 9
  • 70
  • 114
enbermudas
  • 1,603
  • 4
  • 20
  • 42
  • You don't give us enough info about how you dealing with the new column called `code` but you can set it as nullable and its default value to `null`. if this is what you asking about I'll write it as answer – MohamedSabil83 Aug 07 '18 at 00:23
  • I said that i can't set the `code` value for my user/role relationship while using the `assignRole` method. I don't want the `code` to be `null` by default: I want to assign a role AND set an extra field to the `model_has_roles` table while doing it. – enbermudas Aug 07 '18 at 00:47
  • I think that's done in two steps unless you making a change in **assignRole** method – MohamedSabil83 Aug 07 '18 at 00:56
  • But, how can i change the `assignRole` method or what are those two steps like? – enbermudas Aug 07 '18 at 11:57

1 Answers1

1

I see you have already added the column in the migration so now you need to make the changes in the assignRole method.

Spatie permission package works by adding the HasRoles trait in the User model class.

This is the full path of the trait-

use Spatie\Permission\Traits\HasRoles;

To achieve what you desire with the assignRole method, you can simply copy the content from HasRoles trait and then create your own trait from this code. You can see the method in this trait-

    public function assignRole(...$roles)
    {
        $roles = collect($roles)
            ->flatten()
            ->map(function ($role) {
                if (empty($role)) {
                    return false;
                }

                return $this->getStoredRole($role);
            })
            ->filter(function ($role) {
                return $role instanceof Role;
            })
            ->each(function ($role) {
                $this->ensureModelSharesGuard($role);
            })
            ->map->id
            ->all();

        $model = $this->getModel();

        if ($model->exists) {
            $this->roles()->sync($roles, false);
            $model->load('roles');
        } else {
            $class = \get_class($model);

            $class::saved(
                function ($object) use ($roles, $model) {
                    static $modelLastFiredOn;
                    if ($modelLastFiredOn !== null && $modelLastFiredOn === $model) {
                        return;
                    }
                    $object->roles()->sync($roles, false);
                    $object->load('roles');
                    $modelLastFiredOn = $object;
                });
        }

        $this->forgetCachedPermissions();

        return $this;
    }

Make your desired changes in this method and use your custom trait rather than using the spatie's HasRole trait.

Alternatively, you can also override the method from HasRoles trait in your class which is an easier and preferred way.

Pankaj
  • 698
  • 9
  • 21