I have migration file in which I like to assign role to existing user in my DB.
Code fail when try to assign role viewer on user.
I have in my database:
ID | name | guard_name
1 | viewer | api
This is my code in migration file:
foreach (User::all() as $user) {
$user->assignRole('viewer');
}
Can I force some guard or maybe there is some other solution about this problem ?
Could you try clearing you cache between creating and assigning the role?
If you're using the default guard, you don't need to worry about that.
@sebastiandedeyne I try to clear cache but problem still here.
My default guard is web but my role viewer has guard_name = api . Maybe this is the problem but this must be like this because I have users on production and all must have viewer role.
Since you're dealing with multiple guards, instead of passing a string try to assign an actual object with assignRole ($user->assignRole($viewerRole))
Error: The given role or permission should use guardwebinstead ofapi.
viewer role has quard_name = api, but my default guard is set to web. I think that there is the problem...
You can't "share" roles between different guards. Different guards require different roles. If you need need one for two guards, create a second role with the same name.
@sebastiandedeyne I don't not quite understand assignRole($user->assignRole($viewerRole)) you said. I have two different guards, web and api. So how shall I assign a role whose guard_name = api to a registered user?
// register
$user = User::create($inputList);
$user->assignRole($user->assignRole('composer', 'api')); // error
Thanks!
Could you share the configuration of your guards in config/auth.php?
@sebastiandedeyne Here is my config/auth.php
<?php
return [
'defaults' => [
// 'guard' => 'web',
'guard' => 'api',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
// 'driver' => 'token',
// 'driver' => 'passport',
'driver' => 'jwt',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],
];
Think something's wrong on our end here. Created a new issue (#294) to follow this up, I'll try to get to this soon.
@wyudong Could you require in dev-master and see if your issue is resolved?
@sebastiandedeyne I think we've made a step forward. I can now assign role to a user in this way:
$user->assignRole(Role::findByName('composer', 'api'));
I don't know if it is the correct way to assign an actual object with assignRole.
No that's perfect!
If you're using multiple guards, I recommend using objects over strings, otherwise the package needs to guess with role/permission you want to use in the case of having two roles/permissions with the same names and different guards.
I just released these changes in 2.5.1.
@sebastiandedeyne I just released these changes in 2.5.1.
馃槙 The latest version available at the moment is 2.4.2:
I meant 2.1.5 apparently, so this should be resolved!
Still not working for $user->syncRoles('Administrator'). By using @wyudong workaround (Role::findByName('Administrator', 'api')) seems to work, but it does not when I use string.
Extended example of @wyudong answer
public function update(UpdateUserRequest $request, $id)
{
$user = $this->user->findOrFailUuid($id);
$user->fill($request->all());
$user->save();
//sync roles
if ($request->filled('roles')) {
$roles = [];
foreach ($request->roles as $role_name) {
$role = Role::findByName($role_name, 'api');
if ($role) {
$roles[] = $role;
}
}
if (!empty($roles)) {
$user->syncRoles($roles);
}
}
return new UserResource($user->load('roles'));
}
I had the same issue and I solved it by using the Model which is assigned as the provider and in this case its User::class model
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
Most helpful comment
@sebastiandedeyne I think we've made a step forward. I can now assign role to a user in this way:
I don't know if it is the correct way to assign an actual object with assignRole.