Home  >  Q&A  >  body text

Spatie role plugin for Laravel + seed users with roles, no roles assigned

<p>In Laravel 9 I tried adding a role to the user</p> <p>Spatie just processed everything without errors, but in the database the relationship between role and user does not appear in the model for table "model_has_role"</p> <p><code>I created a similar character</code></p> <pre class="brush:php;toolbar:false;">$roleName = 'MyRole'; $guardName = 'myGuard'; $roleObj = Role::create(['guard_name' => $guardName, 'name' => $roleName]);</pre> <p><code>Then create a user, for example </code></p> <pre class="brush:php;toolbar:false;">$user = new User($userDatas);</pre> <p><code>I collected all the data from the model that should be filled in</code></p> <pre class="brush:php;toolbar:false;">$arrayWithUsersData = []; foreach($users as $user) { if($users !== NULL) { $arrayWithUsersData[] = $user->getAttributes(); } }</pre> <p><code>After this, I tried to insert all users into the database at once, so I used </code></p> <pre class="brush:php;toolbar:false;">DB::table('users')->insert($arrayWithUsersData);</pre> <p>Finally I tried any possible way to assign roles in foreach $users Like: </p> <pre class="brush:php;toolbar:false;">$user->assignRole($roleName); $user->assignRole($roleName, $guardName); $user->assignRole([$roleName, $guardName]); $user->assignRole($myRole); $user->assignRole($myRole, $guardName); $user->assignRole([$myRole, $guardName]); $user->syncRoles($myRole); $user->syncRoles($myRole, $guardName); $user->syncRoles([$myRole, $guardName]);</pre> <p>But no error is given but still no relationship is created</p>
P粉637866931P粉637866931382 days ago508

reply all(1)I'll reply

  • P粉216807924

    P粉2168079242023-09-06 19:18:57

    The problem is that the spatie in allocateRole and syncRole works if the model exists

    I mean Laravel model has "exists" attribute

    vendor\spatie\laravel-permission\src\Traits\HasRoles.php contains some code from the allocateRole function

    • syncRoles is a wrapper for allocateRole

      $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) {
                    if ($model->getKey() != $object->getKey()) {
                        return;
                    }
                    $model->roles()->sync($roles, false);
                    $model->load('roles');
                }
            );
        }

    Therefore DB::table('users')->insert($arrayWithUsersData); Do not change the parameter "exists" in the model as it applies to the original data

    So I had to switch to creating users one by one and saving them

    $user = new User($userData);
    $user->save();

    Now Spatie creates the proper relationship.

    reply
    0
  • Cancelreply