php - Laravel - Eloquent 模型不触发事件
问题描述
我正在使用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',
]);
这是我从保镖包(带有 uuids)的迁移:
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');
});
}
解决方案
为了触发模型事件,必须实例化模型。
基本模型示例
对于单个模型(没有关系),这就像选择一个创建语法而不是另一个一样简单:
不触发模型事件
Model::create([
'field' => 'value
]);
触发模型事件
$model = new Model;
$model->field = 'value;
$model->save();
关系示例
对于关系,我们遵循类似的语法。
不触发模型事件
Model::related()->create(['field' => 'value']);
触发模型事件
$model = Model::find(1);
$related = new Related;
$related->field = 'value';
$model->related()->attach($related);
概括
您会注意到这两种类型之间的主要区别在于static
方法调用的使用与首先实际创建new
模型的区别。和类似的create
方法是方便的捷径,但您需要注意这些权衡。
推荐阅读
- sockets - curl "无法连接到服务器"
- reactjs - TypeError: undefined is not an object (评估 '_expo.BarCodeScanner.Constants')
- bixby - 获取用户时区的日期对象
- html - 根据屏幕大小自动排列表格中的项目
- kubernetes - 为 gpu-monitoring-tools 添加密码?
- docker - Docker CE for Windows - 无法建立 SSL 连接。根据验证程序,远程证书无效
- .net-core - 找不到具有 AssemblyQualifiedName、URI 或 FriendlyName 'junit' 的测试记录器
- c - sscanf(str1, "%s %d %f", str2,&num,&float1) 产生意外结果
- macros - 从 Base 扩展 `@show`
- python - 将多索引熊猫数据框渲染为 html 时如何去除多余的单元格?