PHP 7.2 + Laravel 5.8: вызов родительского метода, определенного в Trait, перезаписывается вызовом родительского метода в классе, который использует эту Trait - PullRequest
1 голос
/ 12 июня 2019

Может быть трудно объяснить этот случай с помощью заголовка, поэтому позвольте мне поставить его здесь.

Мне пришлось использовать 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;
    });
}

My Eloquent User использует эту черту.Все работало, но однажды мне пришлось добавить глобальную область действия к User , поэтому я определил в классе пользователя :

protected static function boot()
{
    parent::boot();

    static::addGlobalScope(new UserScopeSalesContactAdmin());
}

enter image description here

Я полностью пропустил это.Теперь моя глобальная область действия работает, но UUID игнорируется. Я, очевидно, знаю, почему это происходит .Я не являюсь автором Boilerplate, и я разработал бы эту архитектуру по-другому, но это хороший учебный пример, поэтому мой вопрос:

Как я могу изменить свой код так, как мои глобальные возможностиработает так же хорошо, как UUID? Я мог бы просто переместить мой addGlobalScope в черту, но это явно глупая идея, так как область действия не имеет ничего общего с UUID, следовательно, это нарушает правило ООП.

edit:

Я сделал наоборот: я скопировал:

static::creating(function ($model) {
     $model->{$model->getUuidName()} = PackageUuid::generate(4)->string;
});

в метод boot в User, но все же я считаю это дублированием ...

Ответы [ 2 ]

0 голосов
/ 12 июня 2019

Вы можете попробовать это, предполагая, что имя черты BoilerplateTrait. Вызовите функцию загрузки BoilerplateTrait изнутри функции загрузки вашей пользовательской модели

protected static function boot()
{
    //parent::boot();
    BoilerplateTrait::boot();
    static::addGlobalScope(new UserScopeSalesContactAdmin());
}
0 голосов
/ 12 июня 2019

Вы можете написать свою собственную черту. Но вместо boot() определите boot<TraitName>():

trait HasUuid
{
    protected static function bootHasUuid()
    {
        static::creating(function ($model) {
            $model->{$model->getUuidName()} = PackageUuid::generate(4)->string; 
        });
    }
}

Таким образом, вам не нужно переопределять boot().

Laravel вызовет специальный метод загрузки признаков, основанный на схеме именования, описанной выше. Это просто плохо документированная функциональность ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...