简体   繁体   English

使用 UUID 分配角色时 Spatie / Permissions 抛出约束失败

[英]Spatie / Permissions throwing constraint failure when assigning Roles using UUID

I have a Laravel 9 project where I am using UUID's.我有一个使用 UUID 的 Laravel 9 项目。 I have just installed the Spatie Permissions package and followed the instructions to use it with UUID's... But when I try to assignRole I am getting the following error;我刚刚安装了 Spatie Permissions package 并按照说明将其与 UUID 一起使用...但是当我尝试分配assignRole时,出现以下错误;

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`project`.`model_has_roles`, CONSTRAINT `model_has_roles_role_id_foreign` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) ON DELETE CASCADE) (SQL: insert into `model_has_roles` (`model_id`, `model_type`, `role_id`) values (1d6535d1-01f0-43b4-8701-4e3c76ad1587, App\Models\User, 0))

I think it might be something to do with the Spatie migration which comes with the package. I have updated it as per https://spatie.be/docs/laravel-permission/v5/advanced-usage/uuid#content-migrations .. as below;我认为这可能与 package 附带的 Spatie 迁移有关。我已根据https://spatie.be/docs/laravel-permission/v5/advanced-usage/uuid#content-migrations进行了更新。 。 如下;

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Spatie\Permission\PermissionRegistrar;

class CreatePermissionTables extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        $tableNames = config('permission.table_names');
        $columnNames = config('permission.column_names');
        $teams = config('permission.teams');

        if (empty($tableNames)) {
            throw new \Exception('Error: config/permission.php not loaded. Run [php artisan config:clear] and try again.');
        }
        if ($teams && empty($columnNames['team_foreign_key'] ?? null)) {
            throw new \Exception('Error: team_foreign_key on config/permission.php not loaded. Run [php artisan config:clear] and try again.');
        }

        Schema::create($tableNames['permissions'], function (Blueprint $table) {
            $table->uuid('id'); // permission id
            $table->string('name');       // For MySQL 8.0 use string('name', 125);
            $table->string('guard_name'); // For MySQL 8.0 use string('guard_name', 125);
            $table->timestamps();

            $table->primary('id');

            $table->unique(['name', 'guard_name']);
        });

        Schema::create($tableNames['roles'], function (Blueprint $table) use ($teams, $columnNames) {
            $table->uuid('id'); // role id
            if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing
                $table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable();
                $table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index');
            }
            $table->string('name');       // For MySQL 8.0 use string('name', 125);
            $table->string('guard_name'); // For MySQL 8.0 use string('guard_name', 125);
            $table->timestamps();

            $table->primary('id');

            if ($teams || config('permission.testing')) {
                $table->unique([$columnNames['team_foreign_key'], 'name', 'guard_name']);
            } else {
                $table->unique(['name', 'guard_name']);
            }
        });

        Schema::create($tableNames['model_has_permissions'], function (Blueprint $table) use ($tableNames, $columnNames, $teams) {
            $table->uuid(PermissionRegistrar::$pivotPermission);

            $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(PermissionRegistrar::$pivotPermission)
                ->references('id') // permission id
                ->on($tableNames['permissions'])
                ->onDelete('cascade');
            if ($teams) {
                $table->unsignedBigInteger($columnNames['team_foreign_key']);
                $table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index');

                $table->primary([$columnNames['team_foreign_key'], PermissionRegistrar::$pivotPermission, $columnNames['model_morph_key'], 'model_type'],
                    'model_has_permissions_permission_model_type_primary');
            } else {
                $table->primary([PermissionRegistrar::$pivotPermission, $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, $teams) {
            $table->uuid(PermissionRegistrar::$pivotRole);

            $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(PermissionRegistrar::$pivotRole)
                ->references('id') // role id
                ->on($tableNames['roles'])
                ->onDelete('cascade');
            if ($teams) {
                $table->unsignedBigInteger($columnNames['team_foreign_key']);
                $table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index');

                $table->primary([$columnNames['team_foreign_key'], PermissionRegistrar::$pivotRole, $columnNames['model_morph_key'], 'model_type'],
                    'model_has_roles_role_model_type_primary');
            } else {
                $table->primary([PermissionRegistrar::$pivotRole, $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(PermissionRegistrar::$pivotPermission);
            $table->uuid(PermissionRegistrar::$pivotRole);

            $table->foreign(PermissionRegistrar::$pivotPermission)
                ->references('id') // permission id
                ->on($tableNames['permissions'])
                ->onDelete('cascade');

            $table->foreign(PermissionRegistrar::$pivotRole)
                ->references('id') // role id
                ->on($tableNames['roles'])
                ->onDelete('cascade');

            $table->primary([PermissionRegistrar::$pivotPermission, PermissionRegistrar::$pivotRole], '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 have a trait for UUID which is as follows;我有一个 UUID 的特征,如下所示;

<?php

declare(strict_types=1);

namespace App\Concerns;

use Illuminate\Support\Str;

trait HasUuid
{
    protected static function boot(): void
    {
        parent::boot();

        static::creating(function ($model) {
            if (empty($model->{$model->getKeyName()})) {
                $model->{$model->getKeyName()} = Str::uuid()->toString();
            }
        });
    }

    public function getIncrementing(): bool
    {
        return false;
    }

    public function getKeyType(): string
    {
        return 'string';
    }
}

I have this on my User model, and also I have extended the Role and Permission model which now looks like this;我在我的用户 model 上有这个,我还扩展了RolePermission model,现在看起来像这样;

<?php

declare(strict_types=1);

namespace App\Models;

use App\Concerns\HasUuid;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Spatie\Permission\Models\Role as SpatieRole;

class Role extends SpatieRole
{
    use HasFactory;
    use HasUuid;
}

The code that it is failing on is the following which is a standard user create, but the assignRole is where it seems to be failing;它失败的代码如下,这是标准用户创建的,但assignRole似乎是失败的地方;

User::create([
    'name' => 'Super Admin',
    'email' => 'super-admin@example.com',
    'password' => Hash::make('password'),
])->assignRole('super-admin');

Any help would be greatly appreciated.任何帮助将不胜感激。

I managed to figure this out if anyone has the same issue.如果有人遇到同样的问题,我设法解决了这个问题。

As I am extending the Role and Permission model, this needs to be reflected in the config/permission.php file由于我正在扩展RolePermission model,这需要反映在config/permission.php文件中

    'models' => [

        /*
         * When using the "HasPermissions" trait from this package, we need to know which
         * Eloquent model should be used to retrieve your permissions. Of course, it
         * is often just the "Permission" model but you may use whatever you like.
         *
         * The model you want to use as a Permission model needs to implement the
         * `Spatie\Permission\Contracts\Permission` contract.
         */

        'permission' => \App\Models\Permission::class,

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * Eloquent model should be used to retrieve your roles. Of course, it
         * is often just the "Role" model but you may use whatever you like.
         *
         * The model you want to use as a Role model needs to implement the
         * `Spatie\Permission\Contracts\Role` contract.
         */

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 UUID 将权限分配给 spatie/laravel-permission 中的角色时的非法偏移类型 - Illegal offset type when assigning Permission into Role in spatie/laravel-permission using UUID 使用 Spatie 权限显示分配给 Laravel 中用户的多个角色 - Showing multiple roles assigned to a user in Laravel using Spatie Permissions Laravel 5.6 - 使用Spatie教程的用户角色和权限(ACL) - Laravel 5.6 - User Roles and Permissions (ACL) using Spatie Tutorial 使用Spatie权限时的Laravel 5.6会话超时异常 - Laravel 5.6 session timeout exception when using spatie permissions Laravel Spatie 角色和权限:如何更改默认表? - Laravel Spatie Roles & Permissions: How to change default tables? 如何在Spatie权限包中列出所有带有Permissions的角色? - How to list all roles with Permissions,in spatie permission Package? 如何分配多个角色和基于多个角色的权限 uning laravel spatie? - How to assign multiple roles and multiple roles based permissions uning laravel spatie? Test中使用Spatie Permissions没有权限 - Using Spatie Permissions in Test doesn't have permissions Laravel 角色与 Spatie package - Laravel roles with Spatie package 完整性约束违规:分配角色时发生 1048 列“user_id”不能为空错误(Laravel 5.3) - Integrity constraint violation: 1048 Column 'user_id' cannot be null error occurs when assigning roles (Laravel 5.3)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM