Laravel-Backpack / PermissionManager

Admin interface for managing users, roles, permissions, using Backpack CRUD
http://backpackforlaravel.com
Other
516 stars 166 forks source link

$user->roles() returning collection of 'false' values #352

Closed gvanto closed 8 months ago

gvanto commented 8 months ago

Bug report

What I did:

Trying to get collection of user's roles:

namespace App\Http\Controllers;

use App\Models\Redirect;
use App\Models\User;
use Backpack\PermissionManager\app\Models\Permission;
use Backpack\PermissionManager\app\Models\Role;
use Illuminate\Http\Request;

class TestController
{

    public function index(Request $request)
    {
        /** @var User $user */
        //$user = backpack_user();
        $user = User::where('name', 'Admin')->first();

        /** @var Role $role */
        foreach ($user->roles() as $role) {
            dd($role); // returns 'false'

            /** @var Permission $permission */
            foreach ($role->permissions() as $permission) {
                dump($permission->name);
            }
        }
    }

What I expected to happen:

dd($role) to dump an object of type 'Backpack\PermissionManager\app\Models\Role'

What happened:

image

What I've already tried to fix it:

Have followed all steps as per README. The user has roles assigned to them (and the roles have permissions assigned to them)

Similar issue: https://github.com/Laravel-Backpack/PermissionManager/issues/169

Backpack, Laravel, PHP, DB version:

Backpack/Crud 6.4, Lara 10.x, MySQL 5.7

pxpm commented 8 months ago

You are getting a fresh instance of the db without any roles associated.

You can eager load them with: User::with('roles')->where('name', 'Admin')->first()

If you are still not getting the expected roles, you may need to check what guard your roles were created for, and what guard you are using in your admin panel.

Cheers

gvanto commented 8 months ago

You are getting a fresh instance of the db without any roles associated.

You can eager load them with: User::with('roles')->where('name', 'Admin')->first()

If you are still not getting the expected roles, you may need to check what guard your roles were created for, and what guard you are using in your admin panel.

Cheers

Thanks a lot @pxpm, but I actually need to get it from authenticated user: How to eager load from loaded object?

$user = backpack_user();

I mean worst case I could do:

User::with('roles')->where('name', backpack_user()->name)->first()

but this seems a bit convoluted.

Maybe something like $user->loadRoles()?

I assume lazyLoading roles is quite difficult then (or why can it not work as with normal relations?)

pxpm commented 8 months ago

If you have the traits properly setup in your User model you should be able to just do: bacpack_user()->hasRole('someRoleName') to check if the user has the desired role. Or ->hasAnyRole(['role1', 'role2']) etc etc.

What I suspect is that your authenticated user is using one guard, and there is no roles for that guard. Please read this package README, section 7a) and 7b) that talk a bit about this.

Let me know if that helps.

gvanto commented 8 months ago

Hi @pxpm thanks but I want to get all the roles for a user, not check whether a user has a particular role

pxpm commented 8 months ago

backpack_user()->getRolesNames() return all the user roles for me. Also backpack_user()->roles()->get() return a collection of role instances.

image

image

If the same is not happening to you, I would check if you roles are properly assigned to the user in the database, and you are using the proper guard for it.

If can also be a cache issue, so I would also suggest for you to clear all the caches with php artisan cache:clear

Let me know if that helps

gvanto commented 8 months ago

Ok this is working, thanks @pxpm.

$user->roles()->get()

Thanks again, loving this package!