У меня есть приложение Laravel 5.7, использующее разрешение spatie / laravel и обычные идентификаторы для моделей. Я хочу перейти на использование UUID и выполнил шаги, указанные в файле Readme webpatser / laravel-uuid. Все работает с моими собственными моделями, например с пользователем, моделью A, моделью B и т. д., и отношения кажутся прекрасными, но я не могу заставить uuid работать с разрешениями Spatie.
Когда я хочу назначить объекту роль (и соответствующие разрешения), я получаю следующую ошибку. Это происходит, когда я пытаюсь зарегистрировать пользователя и назначить ему роль.
Как вы можете видеть на этом изображении, role_id от Spatie передается в этот запрос как целое число. Сейчас это 342, в остальном аналогично 705293.
Я определил черту Uuids.php в моей папке / app соответственно и добавил для всех моделей, включая Permission.php и Role.php следующий код:
public $incrementing = false;
protected $keyType = 'string';
use Uuids;
protected $casts = [
'id' => 'string',
];
Я знаю, что это работает с любой другой моделью и отношением, но только не с разрешениями Spatie, и кажется, что role_id по-другому преобразуется во внутренних функциях (например, assignRole ('') из строки 36chars во что-то еще. Если я запрашиваю Роли или разрешения Я получаю правильный строковый идентификатор.
Что-нибудь, что мне может не хватать, или кто-нибудь знает, как это исправить?
Позднее редактирование: это моя первоначальная миграция для Spatie:
<?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');
Schema::create($tableNames['permissions'], function (Blueprint $table) {
$table->uuid('id');
$table->primary('id');
$table->string('name');
$table->string('guard_name');
$table->timestamps();
});
Schema::create($tableNames['roles'], function (Blueprint $table) {
$table->uuid('id');
$table->primary('id');
$table->string('name');
$table->string('guard_name');
$table->timestamps();
});
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', ]);
$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', ]);
$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']);
app('cache')->forget('spatie.permission.cache');
});
}
//Reverse the migrations.
public function down()
{
$tableNames = config('permission.table_names');
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']);
}
}
Это пример того, как хранятся (работают) роли и разрешения.
То же самое и с разрешениями. Значит, их _id правильный. Проблема заключается в том, что где-то в Laravel или Spatie он отправляет другое значение в БД при попытке добавить роль в модель.






Обновлять таблицы в пакете не рекомендуется. Итак, создайте трейт в папке приложения:
<?php
namespace YourNamespace;
use Illuminate\Support\Str;
trait Uuids
{
/**
* Boot function from Laravel
*/
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
$model->incrementing = false;
$model->{$model->getKeyName()} = Str::uuid()->toString();
});
}
}
Создайте миграцию, чтобы обновить структуру таблицы:
php artisan migrate:make change_primary_key_type_in_roles_table --table=roles
Поместите в миграцию следующее:
public function up()
{
Schema::table('roles', function (Blueprint $table) {
$table->uuid('id')->change();
});
}
public function down()
{
Schema::table('roles', function (Blueprint $table) {
$table->increments('id')->change();
});
}
Используйте трейт Uuid в своей модели:
<?php
namespace YourNamespace;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
use Uuids;
protected $guarded = [''];
protected $casts = [
'id' => 'string',
];
Потом делаем composer dumpautoload и php artisan migrate
Также столкнулся с этой проблемой. решается путем изменения Permission.php и Role.php следующим кодом:
public $incrementing = false;
protected $keyType = 'string';
use Uuids;
protected $casts = [
'id' => 'uuid',
];
К сожалению, не работает. В моей таблице ролей есть $ table-> uuid ('id'); первичный ключ установлен с самого начала. Роли и разрешения правильно добавляются в базу данных, когда я ее заполняю. Затем разрешения правильно назначаются ролям, когда я их засеваю. Проблема возникает, когда я пытаюсь назначить роль модели, поскольку role_id каким-то образом конвертируется в Laravel из char (36) или не отображается как таковой. Прямо как на скриншоте :(