Не добавляется правило валидации в модель через поведение

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Matvik
Сообщения: 194
Зарегистрирован: 2013.06.21, 02:32

Не добавляется правило валидации в модель через поведение

Сообщение Matvik »

Суть такова:
Есть модель (любая). К ней аттаччится поведение со своими дополнительными аттрибутами.
Хочу для этих аттрибутов зарегистрировать правила валидации (например, safe).
Пробую следующим образом (в поведении):

Код: Выделить всё

public function attach($owner)
    {
        parent::attach($owner);
        $owner->validators[] = Validator::createValidator('safe', $owner, ['galleryImagesDelete', 'galleryImagesOrder']);
    }
При этом странная штука - если посмотреть дебаггером, то в этом методе у овнера появляется новый валидатор, но в контроллере сразу после, например, вызова $model->load() (когда срабатывает метод attach() в поведении), его уже нет. Что с этим делать?

Через beforeValidate не подходит, так как массовое присваивание (для которого нужен safe) не вызывает валидацию. В самой модели тоже не изменяется ничего, даже просто
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: Не добавляется правило валидации в модель через поведение

Сообщение andku83 »

$owner->validators - readonly-property
У модели есть свойство $_validators, но к нему похоже доступа не получить.

Попробуйте вот так:

Код: Выделить всё

        parent::attach($owner);
        $validators = $owner->getValidators();
        $validators->append(Validator::createValidator('safe', $owner, ['galleryImagesDelete', 'galleryImagesOrder']);
Идея взята отсюда
Matvik
Сообщения: 194
Зарегистрирован: 2013.06.21, 02:32

Re: Не добавляется правило валидации в модель через поведение

Сообщение Matvik »

andku83 писал(а): 2018.04.12, 18:57 $owner->validators - readonly-property
У модели есть свойство $_validators, но к нему похоже доступа не получить.

Попробуйте вот так:

Код: Выделить всё

        parent::attach($owner);
        $validators = $owner->getValidators();
        $validators->append(Validator::createValidator('safe', $owner, ['galleryImagesDelete', 'galleryImagesOrder']);
Идея взята отсюда
Так тоже не работает. Та же ситуация - в методе аттач добавляется, но в экшне снова дефолтный набор.
Аватара пользователя
SiZE
Сообщения: 2813
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Не добавляется правило валидации в модель через поведение

Сообщение SiZE »

Код: Выделить всё

class MyBehavior extends Behavior
{
    private $isAttached = false;

    public function events()
    {
        return [
            ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate',
        ];
    }

    public function beforeValidate($event)
    {
        if (!$this->isAttached) {
            $validators = $this->owner->getValidators();
            // а тут все остальные валидаторы
            $validators->append(Validator::createValidator('oops', $this->owner, ['galleryImagesDelete', 'galleryImagesOrder']);

            $this->isAttached = true;
        }
    }

    /**
      * @override
      */
    public function safeAttributes()
    {
         return array_unique(array_merge($this->owner->safeAttributes(), [
             'galleryImagesDelete',
             'galleryImagesOrder'
         ]));
    }
}
Matvik
Сообщения: 194
Зарегистрирован: 2013.06.21, 02:32

Re: Не добавляется правило валидации в модель через поведение

Сообщение Matvik »

Код: Выделить всё

/**
      * @override
      */
    public function safeAttributes()
    {
         return array_unique(array_merge($this->owner->safeAttributes(), [
             'galleryImagesDelete',
             'galleryImagesOrder'
         ]));
    }
К сожалению, так не работает, дебагерром проверял, в этот метод не заходит даже.
Matvik
Сообщения: 194
Зарегистрирован: 2013.06.21, 02:32

Re: Не добавляется правило валидации в модель через поведение

Сообщение Matvik »

Видимо, таким через поведение невозможно перекрыть родительский метод модели
Аватара пользователя
SiZE
Сообщения: 2813
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Не добавляется правило валидации в модель через поведение

Сообщение SiZE »

Да, я погорячился с оверрайдом в поведении. Заюзай трейты =)
Matvik
Сообщения: 194
Зарегистрирован: 2013.06.21, 02:32

Re: Не добавляется правило валидации в модель через поведение

Сообщение Matvik »

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

Собственно. не понимаю, почему нельзя через attach(), кто-нибуть может внятно обьяснить? Ведь видно же через дебаггер - у овнера появляется валидатор, а потом пропадает сразу, как так?
Аватара пользователя
SiZE
Сообщения: 2813
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Не добавляется правило валидации в модель через поведение

Сообщение SiZE »

Matvik писал(а): 2018.04.16, 01:24 Собственно. не понимаю, почему нельзя через attach(), кто-нибуть может внятно обьяснить?
можно если проинициализируешь поведение.
Matvik
Сообщения: 194
Зарегистрирован: 2013.06.21, 02:32

Re: Не добавляется правило валидации в модель через поведение

Сообщение Matvik »

kukuruku писал(а): 2018.04.16, 07:49 смотрел мою ссылку?
Смотрел, не нашел там решения.
Matvik
Сообщения: 194
Зарегистрирован: 2013.06.21, 02:32

Re: Не добавляется правило валидации в модель через поведение

Сообщение Matvik »

SiZE писал(а): 2018.04.16, 09:22
Matvik писал(а): 2018.04.16, 01:24 Собственно. не понимаю, почему нельзя через attach(), кто-нибуть может внятно обьяснить?
можно если проинициализируешь поведение.
Можно ссылку? Не понимаю, что значит, "проинициализировать" в данном контексте
kukuruku
Сообщения: 1318
Зарегистрирован: 2011.02.14, 11:36

Re: Не добавляется правило валидации в модель через поведение

Сообщение kukuruku »

специально проверил у себя
создал поведение

Код: Выделить всё

class B extends Behavior
{
    public function attach($owner)
    {
        parent::attach($owner); // TODO: Change the autogenerated stub

        $owner->validators[] = Validator::createValidator('required', $owner, ['name', 'website_email', 'customer_email']);
    }
}
добавил в класс модели, и перечисленные поля начали ругаться что не заполненные
версия 2.0.15
Matvik
Сообщения: 194
Зарегистрирован: 2013.06.21, 02:32

Re: Не добавляется правило валидации в модель через поведение

Сообщение Matvik »

kukuruku писал(а): 2018.04.17, 09:32 специально проверил у себя
создал поведение

Код: Выделить всё

class B extends Behavior
{
    public function attach($owner)
    {
        parent::attach($owner); // TODO: Change the autogenerated stub

        $owner->validators[] = Validator::createValidator('required', $owner, ['name', 'website_email', 'customer_email']);
    }
}
добавил в класс модели, и перечисленные поля начали ругаться что не заполненные
версия 2.0.15
Хм. Интересно. Нужно будет на другой модели проверить.
Аватара пользователя
SiZE
Сообщения: 2813
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Не добавляется правило валидации в модель через поведение

Сообщение SiZE »

Matvik писал(а): 2018.04.17, 04:21 Можно ссылку? Не понимаю, что значит, "проинициализировать" в данном контексте
Метод attach() у поведений вызывается в методе yii\base\Component::ensureBehaviors(). Можешь поиском пройтись по Component и посмотреть где ensureBehaviors() вызывается.
Matvik
Сообщения: 194
Зарегистрирован: 2013.06.21, 02:32

Re: Не добавляется правило валидации в модель через поведение

Сообщение Matvik »

SiZE писал(а): 2018.04.17, 15:59
Matvik писал(а): 2018.04.17, 04:21 Можно ссылку? Не понимаю, что значит, "проинициализировать" в данном контексте
Метод attach() у поведений вызывается в методе yii\base\Component::ensureBehaviors(). Можешь поиском пройтись по Component и посмотреть где ensureBehaviors() вызывается.
Ок, ну понятно, а в конкретном случае, когда новая модель создается, он же вызывается сразу во время создания. И непонятно, почему новосозданные валидаторы удаляются сразу после этого. Я сейчас порешаю другим методом, если это баг конкретного применения, то фиг с ним.
Аватара пользователя
SiZE
Сообщения: 2813
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Не добавляется правило валидации в модель через поведение

Сообщение SiZE »

Matvik писал(а): 2018.04.18, 22:35 Ок, ну понятно, а в конкретном случае, когда новая модель создается, он же вызывается сразу во время создания
Само по себе конечно ничего не должно удаляться
Последний раз редактировалось SiZE 2018.04.19, 11:04, всего редактировалось 1 раз.
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Не добавляется правило валидации в модель через поведение

Сообщение ElisDN »

SiZE писал(а): 2018.04.19, 09:51 Когда создается новая модель поведения автоматически не атачатся (не смотря на то что сказано об этом в мане). attach() вызывается только при инициализации поведений в следствии обращения к несуществующему методу или свойству модели.
В методе BaseActiveRecord::init() при создании вызывается trigger(EVENT_INIT), который запускает ensureBehaviors.
Аватара пользователя
SiZE
Сообщения: 2813
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Не добавляется правило валидации в модель через поведение

Сообщение SiZE »

ElisDN писал(а): 2018.04.19, 10:07 В методе BaseActiveRecord::init() при создании вызывается trigger(EVENT_INIT), который запускает ensureBehaviors.
Действительно, спасибо за поправку. Я по коду смотрел, не учел этот момент.
Ответить