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

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

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

Сообщение Matvik » 2018.04.12, 18:24

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

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

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

Через beforeValidate не подходит, так как массовое присваивание (для которого нужен safe) не вызывает валидацию. В самой модели тоже не изменяется ничего, даже просто

andku83
Сообщения: 418
Зарегистрирован: 2016.07.01, 10:24

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

Сообщение 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']);
Идея взята отсюда

Matvik
Сообщения: 186
Зарегистрирован: 2013.06.21, 02:32

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

Сообщение Matvik » 2018.04.12, 23:32

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
Сообщения: 2554
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

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

Сообщение SiZE » 2018.04.13, 09:01

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

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
Сообщения: 186
Зарегистрирован: 2013.06.21, 02:32

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

Сообщение Matvik » 2018.04.13, 21:23

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

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

Matvik
Сообщения: 186
Зарегистрирован: 2013.06.21, 02:32

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

Сообщение Matvik » 2018.04.14, 03:46

Видимо, таким через поведение невозможно перекрыть родительский метод модели

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

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

Сообщение SiZE » 2018.04.14, 07:36

Да, я погорячился с оверрайдом в поведении. Заюзай трейты =)

Matvik
Сообщения: 186
Зарегистрирован: 2013.06.21, 02:32

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

Сообщение Matvik » 2018.04.16, 01:24

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

Собственно. не понимаю, почему нельзя через attach(), кто-нибуть может внятно обьяснить? Ведь видно же через дебаггер - у овнера появляется валидатор, а потом пропадает сразу, как так?


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

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

Сообщение SiZE » 2018.04.16, 09:22

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

Matvik
Сообщения: 186
Зарегистрирован: 2013.06.21, 02:32

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

Сообщение Matvik » 2018.04.17, 04:20

kukuruku писал(а):
2018.04.16, 07:49
смотрел мою ссылку?
Смотрел, не нашел там решения.

Matvik
Сообщения: 186
Зарегистрирован: 2013.06.21, 02:32

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

Сообщение Matvik » 2018.04.17, 04:21

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

kukuruku
Сообщения: 1203
Зарегистрирован: 2011.02.14, 11:36

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

Сообщение 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

Matvik
Сообщения: 186
Зарегистрирован: 2013.06.21, 02:32

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

Сообщение Matvik » 2018.04.17, 15:12

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
Сообщения: 2554
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

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

Сообщение SiZE » 2018.04.17, 15:59

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

Matvik
Сообщения: 186
Зарегистрирован: 2013.06.21, 02:32

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

Сообщение Matvik » 2018.04.18, 22:35

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

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

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

Сообщение SiZE » 2018.04.19, 09:51

Matvik писал(а):
2018.04.18, 22:35
Ок, ну понятно, а в конкретном случае, когда новая модель создается, он же вызывается сразу во время создания
Само по себе конечно ничего не должно удаляться
Последний раз редактировалось SiZE 2018.04.19, 11:04, всего редактировалось 1 раз.

Аватара пользователя
ElisDN
Сообщения: 4942
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

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

Сообщение ElisDN » 2018.04.19, 10:07

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

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

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

Сообщение SiZE » 2018.04.19, 11:00

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

Ответить