Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

xiolog's avatar

Get roles withCount users trouble

Hi all. I need your help.

I am using laravel_permission (https://spatie.be/docs/laravel-permission/v4) and Livewire.

In tinker I make a request:

Role::with('permissions')->withCount('users')->get()

Everything goes fine as I expect it to.

But when I transfer the same line of code to the Livewire component, I get an error:

Class name must be a valid object or a string

I can't figure out what the problem is.

0 likes
12 replies
Snapey's avatar

show the complete statement?

I assume you have imported Role?

Are you calling this in the render method, the mount method or elewhere?

Show more of the error message, like what line it occurs on

xiolog's avatar
<?php

namespace App\Http\Livewire\Backend;

use Livewire\Component;
use Spatie\Permission\Models\Role;

class Roles extends Component
{
    public function render()
    {
        $roles = Role::with('permissions')->withCount('users')->get();

        return view('livewire.backend.roles', compact('roles'));
    }
}

The mistake in the

vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php:745

I understand that the error is part of the code withCount('users'), but I do not understand how to solve this error.

The Roles model doesn't seem to know anything about the Users model. But I don't think I need to write code in the vendor directory. And I don't know how to override the Roles model and specify the relationship there.

Snapey's avatar

is it same role class when you tried in tinker

xiolog's avatar

Yes, it is. I used use Spatie\Permission\Models\Role

xiolog's avatar

This is a response from tinker:

Spatie\Permission\Models\Role {#4610
         id: 2,
         name: "manager",
         label: "Manager",
         guard_name: "web",
         created_at: "2021-02-08 19:10:05",
         updated_at: "2021-02-08 19:10:05",
         users_count: 1,
         permissions: Illuminate\Database\Eloquent\Collection {#4606
           all: [
             Spatie\Permission\Models\Permission {#4630
               id: 1,
               name: "manage_subscriptions",
               guard_name: "web",
               created_at: "2021-02-08 19:10:03",
               updated_at: "2021-02-08 19:10:03",
               pivot: Illuminate\Database\Eloquent\Relations\Pivot {#4620
                 role_id: 2,
                 permission_id: 1,
               },
             },
           ],
         },
       }

All works fine.

But the code in the component still does not work

automica's avatar

Can you post how you’re added this to your livewire component?

xiolog's avatar
xiolog
OP
Best Answer
Level 5

Very strange.

If I use this in the Roles component:

<?php

namespace App\Http\Livewire\Backend;

use Livewire\Component;
use Spatie\Permission\Models\Role;

class Roles extends Component
{
    public function render()
    {
//        $roles = Role::with('permissions')->withCount('users')->get();
        $roles = Role::with('permissions')->get();

        return view('livewire.backend.roles', compact('roles'));
    }
}

and this in the roles.blade.php:

@foreach($roles as $role)
	<tr class="text-sm">
		<td class="py-1">{{ $role->label ?: '-' }}</td>
		<td class="py-1 text-center">{{ $role->name }}</td>
		<td class="py-1 text-center">{{ $role->permissions->pluck('name')->implode(', ') ?: 'Без ограничений' }}</td>
		<td class="whitespace-nowrap py-1 text-center">{{ $role->users->count() }}</td>
</tr>
@endforeach
                	

all works fine.

umairparacha's avatar

I am also facing the same error. 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
shane@bjja.com.au's avatar

I have this exact issue... using spatie/laravel-permission package with livewire, trying to do

Role::query()->withCount(['permissions', 'users'])->get()

from livewire component and get the same error. However i can run the exact same code from Tinker with no errors.

shane@bjja.com.au's avatar

Hi xiolog,

I solved the issue, at least have a workaround. I know this is a year on, but just in case someone else runs into it. It seems to me that Spatie\laravel-permission package is trying to get the user model and because the web route is using auth:sanctum, it is returning null. I changed my web route from auth:sanctum middleware to auth and the problem goes away

2 likes

Please or to participate in this conversation.