可能很难通过标题来解释这种情况,所以让我放在这里。
我不得不使用Laravel Boilerplate。它对模型使用UUID。它有一个trait
,在创建用户模型时会添加UUID。
protected static function boot() // this is in the trait
{
parent::boot();
static::creating(function ($model) {
$model->{$model->getUuidName()} = PackageUuid::generate(4)->string;
});
}
我的口才User
使用此特征。一切正常,但是有一天我不得不将全局范围添加到User
,所以我在User类中定义了:
protected static function boot()
{
parent::boot();
static::addGlobalScope(new UserScopeSalesContactAdmin());
}
我完全错过了。现在,我的全局作用域起作用了,但是UUID被忽略了。 我显然知道为什么会这样。我不是Boilerplate的作者,我将以不同的方式来构建它,但这是一个很好的教育案例,因此我的问题是:
如何更改我的全局作用域和UUID的工作方式?我可以简单地将addGlobalScope
移至特征,但这显然是愚蠢的想法,因为作用域具有与UUID无关,因此违反了OOP规则。
编辑:
我做了另一种方法:复制:
static::creating(function ($model) {
$model->{$model->getUuidName()} = PackageUuid::generate(4)->string;
});
转到boot
中的User
方法,但是我仍然认为这是重复的…
答案 0 :(得分:0)
您可以编写自己的特征。但是请定义boot()
而不是boot<TraitName>()
:
trait HasUuid
{
protected static function bootHasUuid()
{
static::creating(function ($model) {
$model->{$model->getUuidName()} = PackageUuid::generate(4)->string;
});
}
}
通过这种方式,您无需覆盖boot()
。
Laravel将基于上述命名方案调用特质的特殊启动方法。只是没有充分记录的功能...
答案 1 :(得分:0)
您可以在假设特征名称为BoilerplateTrait的情况下尝试此操作。从用户模型的启动功能中调用BoilerplateTrait启动功能
protected static function boot()
{
//parent::boot();
BoilerplateTrait::boot();
static::addGlobalScope(new UserScopeSalesContactAdmin());
}