【发布时间】:2021-09-19 02:20:31
【问题描述】:
我正在使用https://github.com/JosephSilber/bouncer 包。我目前正在努力使其与 UUID 而不是典型的 int 标识符一起使用。从问题中我发现了如何做到这一点:https://github.com/JosephSilber/bouncer/issues/256.
问题是创建角色/能力最终会出错:
SQLSTATE[23000]:[Microsoft][ODBC Driver 17 for SQL Server][SQL Server]无法将值 NULL 插入到列“id”、表“db.dbo.roles”中;列不允许空值。插入失败。 (SQL: insert into [roles] ([name], [title], [updated_at], [created_at]) 值 (Users, User, 2021-07-08 15:22:46.247, 2021-07-08 15:22 :46.247))
我的数据库中有 uuid 而不是 id,因此我在自定义角色/能力模型中创建了一个引导方法来捕获 creating 事件,如下所示:
trait BouncerUuidTrait
{
public static function boot(){
parent::boot();
// NEVER REACHING HERE
self::creating(function ($model) {
$model->incrementing = false;
$model->{$model->getKeyName()} = Str::uuid()->toString();
});
}
}
我的自定义角色类示例:
use Silber\Bouncer\Database\Role as BouncerRole;
class Role extends BouncerRole
{
use BouncerUuidTrait;
public $incrementing = false;
protected $fillable = ['id', 'name', 'title'];
}
创建角色的逻辑:
$role = Bouncer::role()->firstOrCreate([
'name' => LDAPInterface::LDAP_GROUP_WCR_USERS,
'title' => 'User',
]);
这是我从保镖包(带有 uuid)的迁移:
public function up()
{
Schema::create(Models::table('abilities'), function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('name');
$table->string('title')->nullable();
$table->bigInteger('entity_id')->unsigned()->nullable();
$table->string('entity_type')->nullable();
$table->boolean('only_owned')->default(false);
$table->json('options')->nullable();
$table->integer('scope')->nullable()->index();
$table->timestamps();
});
Schema::create(Models::table('roles'), function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('name');
$table->string('title')->nullable();
$table->integer('level')->unsigned()->nullable();
$table->integer('scope')->nullable()->index();
$table->timestamps();
$table->unique(
['name', 'scope'],
'roles_name_unique'
);
});
Schema::create(Models::table('assigned_roles'), function (Blueprint $table) {
$table->bigIncrements('id');
$table->uuid('role_id')->index();
$table->bigInteger('entity_id')->unsigned();
$table->string('entity_type');
$table->bigInteger('restricted_to_id')->unsigned()->nullable();
$table->string('restricted_to_type')->nullable();
$table->integer('scope')->nullable()->index();
$table->index(
['entity_id', 'entity_type', 'scope'],
'assigned_roles_entity_index'
);
$table->foreign('role_id')
->references('id')->on(Models::table('roles'))
->onUpdate('cascade')->onDelete('cascade');
});
Schema::create(Models::table('permissions'), function (Blueprint $table) {
$table->bigIncrements('id');
$table->uuid('ability_id')->index();
$table->uuid('entity_id')->nullable();
$table->string('entity_type')->nullable();
$table->boolean('forbidden')->default(false);
$table->integer('scope')->nullable()->index();
$table->index(
['entity_id', 'entity_type', 'scope'],
'permissions_entity_index'
);
$table->foreign('ability_id')
->references('id')->on(Models::table('abilities'))
->onUpdate('cascade')->onDelete('cascade');
});
}
【问题讨论】:
-
我相信这类似于删除事件中的this issue。您永远不会真正实例化模型,因此不会触发任何事件。
-
尝试澄清一下:
Bouncer::role()->firstOrCreate()只是查询构建器(当点击“创建”部分时),您实际上永远不会获得模型实例。因此,没有触发 model 事件是有道理的。 -
如果我是对的,这负责实例化模型:
Bouncer::role()。那么应该如何创建模型来触发creating事件呢? -
不,访问关系仍然只是查询构建器。请注意,您正在静态使用该方法,而不是像
$r = new Role; $r->create()那样实际上有一个模型实例。 -
$role = new Role(); $role->name = LDAPInterface::LDAP_GROUP_WCR_USERS; $role->title = 'User'; $role->create();此代码也不会触发