spatie/laravel-permission

Target class [app\Models\Permission] does not exist.

mhelleb opened this issue · 6 comments

Hi, I'm having trouble implementing your permissions package
[Laravel-permission v.4] [PHP 7.4.15] [Laravel Framework 6.20.44].

All migrations and seeding work & 'your' databases are filled correctly, but obviously I'm doing something wrong in the binding department ... let's just say that's not my forte ... I really hope you can point me in the right direction!

When I run > php artisan permission:show, I get the following error message:

Illuminate\Contracts\Container\BindingResolutionException  : Target class [app\Models\Permission] does not exist.

When I try logging on into my app a similar error occurs in the log:

Uncaught ReflectionException: Class app\\Models\\Permission does not exist in /var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php:803
Stack trace:
#0 /var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php(803): ReflectionClass->__construct('app\\\\Models\\\\Perm...')
#1 /var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php(681): Illuminate\\Container\\Container->build('app\\\\Models\\\\Perm...')
#2 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(785): Illuminate\\Container\\Container->resolve('app\\\\Models\\\\Perm...', Array, true)
#3 /var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php(629): Illuminate\\Foundation\\Application->resolve('app\\\\Models\\\\Perm...', Array)
#4 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(770): Illuminate\\Container\\Container->make('app\\\\Models\\\\Perm...', Array)
#5 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/helpers.ph at /var/www/html/vendor/laravel/framework/src/Illuminate/Container/Container.php:805)
[stacktrace]

This might be because we already extended our User model from a base model in our application and we tried to work around that like this (3 files shown below; models\User & models\Permission & config\permission), by using interfaces and traits separately in the User model:
== File: App\Models\User.php ==

<?php
namespace App\Models;

use App\Http\Traits\AuthenticationLogable;
use Illuminate\Support\Facades\Config;
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Spatie\Permission\Traits\HasRoles;

class User extends \App\Models\BaseModel implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract
{

    use HasRoles, Authenticatable, Authorizable, CanResetPassword, AuthenticationLogable;

    protected $table = 't_users';

etc.

== File: App\Models\Permission.php ==

<?php
namespace App\Models;

use Spatie\Multitenancy\Models\Concerns\UsesTenantConnection;
use Spatie\Permission\Models\Permission as SpatiePermission;

class Permission extends SpatiePermission
{
    use UsesTenantConnection;

    public static $rules = array(
        "name" => "required",
    );

    public static function getFieldsOpenForEdit()
    {  
        return array("name", "display_name", "description", "created_at", "updated_at");
    }

}

== File: config\permission.php ==

<?php
return [
    'models' => [
          'permission' => app\Models\Permission::class,    // also tried an extra \ up front
          'role' => app\Models\Role::class,
    ],

ETC. = unchanged =

The file content seems to be mixed up in the original post, I'll separate them:
File: App\Models\User.php

<?php
namespace App\Models;

use App\Http\Traits\AuthenticationLogable;
use Illuminate\Support\Facades\Config;
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Spatie\Permission\Traits\HasRoles;

class User extends \App\Models\BaseModel implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract
{

    use HasRoles, Authenticatable, Authorizable, CanResetPassword, AuthenticationLogable;

    protected $table = 't_users';

etc.

File: App\Models\Permission.php

<?php
namespace App\Models;

use Spatie\Multitenancy\Models\Concerns\UsesTenantConnection;
use Spatie\Permission\Models\Permission as SpatiePermission;

class Permission extends SpatiePermission
{
    use UsesTenantConnection;

    public static $rules = array(
        "name" => "required",
    );

    public static function getFieldsOpenForEdit()
    {  
        return array("name", "display_name", "description", "created_at", "updated_at");
    }

}

File: config\permission.php

<?php
return [
    'models' => [
          'permission' => app\Models\Permission::class,    // also tried an extra \ up front
          'role' => app\Models\Role::class,
    ],

ETC. = unchanged =

Laravel-Permission V4 has no support, just V5 has support
Also Laravel Framework 6 has no support

Please, learn to use markdown, the code is impossible to understand

Maybe you forget to clean config cache

Issue is resolved => by re-defining all interfaces and traits in the user model.
Also implemented Spatie\Permission\Contracts\Permission in our Permission model and similar for Spatie\Permission\Contracts\Role in Role model.

Add the built-in middleware list, as described in the documentation

protected $routeMiddleware = [
    // ...
    'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
    'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
    'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class,
];