spatie / laravel-permission

Associate users with roles and permissions
https://spatie.be/docs/laravel-permission
MIT License
12.05k stars 1.76k forks source link

with or withCount with users relation shows an error. #1784

Closed umairparacha00 closed 3 years ago

umairparacha00 commented 3 years ago

with or withCount works with permissions relation but when you add users relation it shows an error.

And also when you do it on tinker it goes completely fine. Very strange

My code

$roles = QueryBuilder::for(Role::class)
            ->allowedSorts('name')
            ->withCount('users')
            ->withCount('permissions')
            ->where('name', '!=', 'owner')
            ->where('guard_name', 'web')
            ->where('user_id', $user->id)
            ->get(['name', 'id']);
        return inertia('roles/staff/Index', ['roles' => $roles]);

Error

Class name must be a valid object or a string
rsecor commented 3 years ago

Same issue here.

Just a simple... $roles = Role::withCount('users')->get();

Yields [2021-07-20 15:14:05] local.ERROR: Class name must be a valid object or a string {"userId":1,"exception":"[object] (Error(code: 0): Class name must be a valid object or a string at /laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php:745)

rsecor commented 3 years ago

In case it helps here is more information from the stacktrace...

2 /laravel/vendor/spatie/laravel-permission/src/Models/Role.php(68): Illuminate\Database\Eloquent\Model->morphedByMany()

erikn69 commented 3 years ago

@rsecor i did try dd(\Spatie\Permission\Models\Role::withCount('users')->get()); And there is no problem image

Using

"laravel/fortify": "^1.7.14",
"laravel/framework": "^8.51.0",
"spatie/laravel-permission": "^4.2.0"
rsecor commented 3 years ago

@erikn69 In composer.json: "laravel/fortify": "^1.7", "laravel/framework": "^8.51", "spatie/laravel-permission": "^4.2" From listed composer installed packages: laravel/fortify v1.7.14 Backend controllers and scaffolding for Laravel authentication. laravel/framework v8.51.0 The Laravel Framework. spatie/laravel-permission 4.2.0 Permission handling for Laravel 6.0 and up

Tried dd(\Spatie\Permission\Models\Role::withCount('users')->get()); And received back Class name must be a valid object or a string vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php:745

Thoughts?

erikn69 commented 3 years ago

@rsecor we have the same, also PHP 8.0.5 maybe any change on config auth.providers.users.model?

'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
///
'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],

custom changes on permission.php, or User.php? permission.column_names.model_morph_key? custom user primary key?

I can't replicate your error, but /spatie/laravel-permission/src/Models/Role.php(68) only get model_morph_key

https://github.com/spatie/laravel-permission/blob/0e39dcca89f01432207c1cbc1661ce06608ff52c/src/Models/Role.php#L63-L69

rsecor commented 3 years ago

PHP 7.4.16 All that looks exactly the way it was installed as default.

erikn69 commented 3 years ago

Tried PHP 7.4 and all exactly the way it was installed as default and still no error(i did make a clean laravel instalation) 😕 I can`t help, sorry

rsecor commented 3 years ago

Curious... @erikn69 What authentication package are you using and how do you have it setup?

erikn69 commented 3 years ago

I did follow documentation indications

  "require": {
        "php": "^7.3|^8.0",
        "fideloper/proxy": "^4.4",
        "fruitcake/laravel-cors": "^2.0",
        "guzzlehttp/guzzle": "^7.0.1",
        "laravel/fortify": "^1.7",
        "laravel/framework": "^8.51",
        "laravel/tinker": "^2.5",
        "spatie/laravel-permission": "^4.2"
    },
    "require-dev": {
        "facade/ignition": "^2.5",
        "fakerphp/faker": "^1.9.1",
        "laravel/sail": "^1.0.1",
        "mockery/mockery": "^1.4.2",
        "nunomaduro/collision": "^5.0",
        "phpunit/phpunit": "^9.3.3"
    },

image

rsecor commented 3 years ago

Wondering if sanctum or some other package is causing an issue.

"require": {
    "php": "^7.3|^8.0",
    "fideloper/proxy": "^4.4",
    "fruitcake/laravel-cors": "^2.0",
    "guzzlehttp/guzzle": "^7.0.1",
    "laravel/fortify": "^1.7",
    "laravel/framework": "^8.51",
    "laravel/jetstream": "^2.3",
    "laravel/sanctum": "^2.6",
    "laravel/tinker": "^2.5",
    "laravel/ui": "^3.3",
    "livewire/livewire": "^2.5",
    "spatie/laravel-dashboard": "^2.0",
    "spatie/laravel-permission": "^4.2"
},
"require-dev": {
    "facade/ignition": "^2.5",
    "fakerphp/faker": "^1.9.1",
    "laravel/sail": "^1.0.1",
    "mockery/mockery": "^1.4.2",
    "nunomaduro/collision": "^5.0",
    "phpunit/phpunit": "^9.3.3"
},
erikn69 commented 3 years ago

@rsecor try this, go to vendor /spatie/laravel-permission/src/Models/Role.php(68) and before return put dd(config('permission.column_names.model_morph_key')); then run \Spatie\Permission\Models\Role::withCount('users')->get();, and keep searching till find the error Also if you are using laravel/fortify maybe you have to remove laravel/ui and upgrade your code I'm not using laravel/sanctum but i use laravel/passport without problems

rsecor commented 3 years ago

@erikn69 Using the information you gave I found that... $this->attributes['guard_name'] = "sanctum" getModelForGuard($this->attributes['guard_name']) = null config('permission.table_names.model_has_roles') = "model_has_roles" config('permission.column_names.model_morph_key') = "model_id"

After som digging... auth.guards array:3 [â–¼ "web" => array:2 [â–¼ "driver" => "session" "provider" => "users" ] "api" => array:3 [â–¼ "driver" => "token" "provider" => "users" "hash" => false ] "sanctum" => array:2 [â–¼ "driver" => "sanctum" "provider" => null ] ]

Odd.

erikn69 commented 3 years ago

There is, you have to handle sanctum guard_name Add a config and try

'guards' => [
        'sanctum' => [
            'driver' => 'sanctum',
            'provider' => 'users',
        ],

It's an idea, I don't use sanctum, maybe it's wrong

rsecor commented 3 years ago

Adding that blows everything up. I might try starting over... mostly just working on getting a good base together I can constantly reuse for projects that need custom programming.

erikn69 commented 3 years ago

Adding that blows everything up

You have to add roles and permissions with guard_name 'sanctum' on db too, or use a wildcard '*' https://github.com/spatie/laravel-permission/issues/1156#issuecomment-781811498 https://spatie.be/docs/laravel-permission/v4/basic-usage/multiple-guards