When I try create a Role:

In the Roles and Permissions models, I put to force these attributes but still returns the error mentioned above.


When creating, failed when looking for role relationship with permission model

It would seem that your alterations for UUID are not consistently matching up across tables: perhaps you didn't alter the schema completely in all affected tables?
Specifically the error is a complaint by Postgres when trying to do the whereIn matching on int vs uuid/string. The protected $keyType='string' should handle this.
Also, unrelated: you should never set id as a $fillable property!!!! (especially if it's your primary key)! Read the Laravel docs around security reasons why the $fillable property exists!
I found the problem, I extends the Spatie\Permission\Models\Permission in my Permission.php,
and I set the $keyType='string' to override, but, for some reason, the Spatie\Permission\Models\Permission, don't override the Illuminate\Database\Eloquent\Model.

If I override this $keyType='string' in Spatie\Permission\Models\Permission, it's work.

Some ideia for resolve this situation, please?
about the id in fillable, thanks for alert, I will improve and studied this.
I would have expected that extending the Spatie Permission model would also allow you to override $keyType as you've done.
Is it possible that your code is (somewhere) using the Spatie model directly and not using your overridden model?
Nevertheless, it is okay to implement the Contract instead of merely extending the Spatie model.
I believe not, I reviewed all the code, however, the only place where I use Spatie model, is in Permission and Role. I changed all my models to override $ keyType = 'string', but it still didn't work :/
I believe there's something wrong in your app.
I've set up a very simple app which extends the Spatie models, and it works fine with assignRole(), syncRoles(), givePermissionTo(), syncPermissions(), with uuid implemented simply.
.env file, specifying Postgres
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_DATABASE=uuidtest
UuidTrait.php
<?php
namespace App;
use Facades\Str;
trait UuidTrait
{
public $incrementing = false;
protected $keyType = 'string';
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
$model->{$model->getKeyName()} = (string) Str::uuid();
});
}
}
User.php
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use Notifiable;
use HasRoles;
use UuidTrait;
}
Role.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Spatie\Permission\Models\Role as SpatieRole;
class Role extends SpatieRole
{
use UuidTrait;
}
Permission.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Spatie\Permission\Models\Permission as SpatiePermission;
class Permission extends SpatiePermission
{
use UuidTrait;
}
config/permissions.php
<?php
return [
'models' => [
'permission' => App\Permission::class,
'role' => App\Role::class,
],
/// the rest of this file is just defaults:
'table_names' => [
'roles' => 'roles',
'permissions' => 'permissions',
'model_has_permissions' => 'model_has_permissions',
'model_has_roles' => 'model_has_roles',
'role_has_permissions' => 'role_has_permissions',
],
'column_names' => [
'model_morph_key' => 'model_id',
],
'display_permission_in_exception' => false,
'enable_wildcard_permission' => false,
'cache' => [
'expiration_time' => \DateInterval::createFromDateString('24 hours'),
'key' => 'spatie.permission.cache',
'model_key' => 'name',
'store' => 'default',
],
];
migration (sets uuid() columns, and sets primary key on role/permission tables):
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePermissionTables extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$tableNames = config('permission.table_names');
$columnNames = config('permission.column_names');
if (empty($tableNames)) {
throw new \Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding.');
}
Schema::create($tableNames['permissions'], function (Blueprint $table) {
$table->uuid('id');
$table->string('name');
$table->string('guard_name');
$table->timestamps();
$table->primary('id');
});
Schema::create($tableNames['roles'], function (Blueprint $table) {
$table->uuid('id');
$table->string('name');
$table->string('guard_name');
$table->timestamps();
$table->primary('id');
});
Schema::create($tableNames['model_has_permissions'], function (Blueprint $table) use ($tableNames, $columnNames) {
$table->uuid('permission_id');
$table->string('model_type');
$table->uuid($columnNames['model_morph_key']);
$table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index');
$table->foreign('permission_id')
->references('id')
->on($tableNames['permissions'])
->onDelete('cascade');
$table->primary(['permission_id', $columnNames['model_morph_key'], 'model_type'],
'model_has_permissions_permission_model_type_primary');
});
Schema::create($tableNames['model_has_roles'], function (Blueprint $table) use ($tableNames, $columnNames) {
$table->uuid('role_id');
$table->string('model_type');
$table->uuid($columnNames['model_morph_key']);
$table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index');
$table->foreign('role_id')
->references('id')
->on($tableNames['roles'])
->onDelete('cascade');
$table->primary(['role_id', $columnNames['model_morph_key'], 'model_type'],
'model_has_roles_role_model_type_primary');
});
Schema::create($tableNames['role_has_permissions'], function (Blueprint $table) use ($tableNames) {
$table->uuid('permission_id');
$table->uuid('role_id');
$table->foreign('permission_id')
->references('id')
->on($tableNames['permissions'])
->onDelete('cascade');
$table->foreign('role_id')
->references('id')
->on($tableNames['roles'])
->onDelete('cascade');
$table->primary(['permission_id', 'role_id'], 'role_has_permissions_permission_id_role_id_primary');
});
app('cache')
->store(config('permission.cache.store') != 'default' ? config('permission.cache.store') : null)
->forget(config('permission.cache.key'));
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
$tableNames = config('permission.table_names');
if (empty($tableNames)) {
throw new \Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.');
}
Schema::drop($tableNames['role_has_permissions']);
Schema::drop($tableNames['model_has_roles']);
Schema::drop($tableNames['model_has_permissions']);
Schema::drop($tableNames['roles']);
Schema::drop($tableNames['permissions']);
}
}
I created a new project just like you did and compared the changes in the projects. Then, I identified that I had not changed in my config/Permissions.php and set to my Models and not Spatie. Anyway, problem solved.
'models' => [
'permission' => App\Permission::class,
'role' => App\Role::class,
],
Thank you very much for your support
Most helpful comment
I created a new project just like you did and compared the changes in the projects. Then, I identified that I had not changed in my
config/Permissions.phpand set to myModelsand notSpatie. Anyway, problem solved.'models' => [ 'permission' => App\Permission::class, 'role' => App\Role::class, ],Thank you very much for your support