Search code examples
phplaraveleloquentlaravel-11

Cannot delete role in laravel permission by spatie


I'm using laravel permission package in my laravel 11 app. Below is my role model

<?php

namespace App\Models;
use Illuminate\Support\Collection;
use Spatie\Permission\Models\Role as SpatieRole;

class Role extends SpatieRole
{
    protected $table = 'roles';
    protected $fillable = [
        'name',
        'guard_name',
        'status',
        'description',
    ];

    public function scopeFilter($query, array $filter)
    {
        $query->when($filter['search'] ?? null, function ($query, $search) {
            $query->where('name', 'like', '%'.$search.'%');
        })
            ->when($filter['trashed'] ?? null, function ($query, $trashed) {
                if ($trashed === 'with') {
                    $query->withTrashed();
                } elseif ($trashed === 'only') {
                    $query->onlyTrashed();
                }
            })
            ->when($filter['status'] ?? null, function ($query, $status) {
                $query->where('status', $status === 'active' ? 1 : 0);
            })
            ->when($filter['from'] ?? null, function ($query, $from) {
                $query->whereDate('created_at', '>=', $from);
            })
            ->when($filter['to'] ?? null, function ($query, $to) {
                $query->whereDate('created_at', '<=', $to);
            });
    }

    public static function getUsersByRole(array $roleNames)
    {
        $roles = self::whereIn('name', $roleNames)->get();

        // Initialize an array to store users
        $users = new Collection();

        foreach ($roles as $role) {
            // Get users with the specific role
            $usersInRole = $role->adminUsers;

            // Merge users from different roles (without duplicates)
            $users = $users->concat($usersInRole);
        }

        return $users->unique('id'); // Remove duplicate users by their id
    }


    public function adminUsers(): \Illuminate\Database\Eloquent\Relations\MorphToMany
    {
        return $this->morphedByMany(AdminUser::class, 'model', 'model_has_roles', 'role_id', 'model_id');

    }


}

My method to delete a role:

    use App\Models\Role;
    public function deleteRole(string $id)
    {
        return DB::transaction(function () use ($id) {

            $role = Role::findOrFail($id);
            $role->delete();

        });
    }

In Permission.php

'role' => App\Models\Role::class,

I get the following error while deleting the role:

Class name must be a valid object or a string {"user_id":"4","exception":"[object] (Error(code: 0): Class name must be a valid object or a string at /var/www/resimator/fundis-api/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php:853)

My database records are: roles table model_has_roles table


Solution

  • Correct code for relationship is

        public function users(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
        {
            return $this->morphedByMany(
                AdminUser::class,
                'model',
                config('permission.table_names.model_has_roles'),
                app(PermissionRegistrar::class)->pivotRole,
                config('permission.column_names.model_morph_key')
            );
        } 
    

    It can be found on Spatie\Permission\Models\Role.