Страница 1 из 1
Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.12, 18:24
Matvik
Суть такова:
Есть модель (любая). К ней аттаччится поведение со своими дополнительными аттрибутами.
Хочу для этих аттрибутов зарегистрировать правила валидации (например, safe).
Пробую следующим образом (в поведении):
Код: Выделить всё
public function attach($owner)
{
parent::attach($owner);
$owner->validators[] = Validator::createValidator('safe', $owner, ['galleryImagesDelete', 'galleryImagesOrder']);
}
При этом странная штука - если посмотреть дебаггером, то в этом методе у овнера появляется новый валидатор, но в контроллере сразу после, например, вызова $model->load() (когда срабатывает метод attach() в поведении), его уже нет. Что с этим делать?
Через beforeValidate не подходит, так как массовое присваивание (для которого нужен safe) не вызывает валидацию. В самой модели тоже не изменяется ничего, даже просто
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.12, 18:57
andku83
$owner->validators - readonly-property
У модели есть свойство $_validators, но к нему похоже доступа не получить.
Попробуйте вот так:
Код: Выделить всё
parent::attach($owner);
$validators = $owner->getValidators();
$validators->append(Validator::createValidator('safe', $owner, ['galleryImagesDelete', 'galleryImagesOrder']);
Идея взята
отсюда
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.12, 23:32
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']);
Идея взята
отсюда
Так тоже не работает. Та же ситуация - в методе аттач добавляется, но в экшне снова дефолтный набор.
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.13, 08:36
kukuruku
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.13, 09:01
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'
]));
}
}
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.13, 21:23
Matvik
Код: Выделить всё
/**
* @override
*/
public function safeAttributes()
{
return array_unique(array_merge($this->owner->safeAttributes(), [
'galleryImagesDelete',
'galleryImagesOrder'
]));
}
К сожалению, так не работает, дебагерром проверял, в этот метод не заходит даже.
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.14, 03:46
Matvik
Видимо, таким через поведение невозможно перекрыть родительский метод модели
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.14, 07:36
SiZE
Да, я погорячился с оверрайдом в поведении. Заюзай трейты =)
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.16, 01:24
Matvik
Да ну не, плохо так. Это ж тогда отдельно от поведения еще трейт придется присобачивать в модель каждый раз, а хотелось бы, чтоб все в одном поведении.
Собственно. не понимаю, почему нельзя через attach(), кто-нибуть может внятно обьяснить? Ведь видно же через дебаггер - у овнера появляется валидатор, а потом пропадает сразу, как так?
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.16, 07:49
kukuruku
смотрел мою ссылку?
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.16, 09:22
SiZE
Matvik писал(а): ↑2018.04.16, 01:24
Собственно. не понимаю, почему нельзя через attach(), кто-нибуть может внятно обьяснить?
можно если проинициализируешь поведение.
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.17, 04:20
Matvik
kukuruku писал(а): ↑2018.04.16, 07:49
смотрел мою ссылку?
Смотрел, не нашел там решения.
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.17, 04:21
Matvik
SiZE писал(а): ↑2018.04.16, 09:22
Matvik писал(а): ↑2018.04.16, 01:24
Собственно. не понимаю, почему нельзя через attach(), кто-нибуть может внятно обьяснить?
можно если проинициализируешь поведение.
Можно ссылку? Не понимаю, что значит, "проинициализировать" в данном контексте
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.17, 09:32
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
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.17, 15:12
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
Хм. Интересно. Нужно будет на другой модели проверить.
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.17, 15:59
SiZE
Matvik писал(а): ↑2018.04.17, 04:21
Можно ссылку? Не понимаю, что значит, "проинициализировать" в данном контексте
Метод attach() у поведений вызывается в методе yii\base\Component::ensureBehaviors(). Можешь поиском пройтись по Component и посмотреть где ensureBehaviors() вызывается.
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.18, 22:35
Matvik
SiZE писал(а): ↑2018.04.17, 15:59
Matvik писал(а): ↑2018.04.17, 04:21
Можно ссылку? Не понимаю, что значит, "проинициализировать" в данном контексте
Метод attach() у поведений вызывается в методе yii\base\Component::ensureBehaviors(). Можешь поиском пройтись по Component и посмотреть где ensureBehaviors() вызывается.
Ок, ну понятно, а в конкретном случае, когда новая модель создается, он же вызывается сразу во время создания. И непонятно, почему новосозданные валидаторы удаляются сразу после этого. Я сейчас порешаю другим методом, если это баг конкретного применения, то фиг с ним.
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.19, 09:51
SiZE
Matvik писал(а): ↑2018.04.18, 22:35
Ок, ну понятно, а в конкретном случае, когда новая модель создается, он же вызывается сразу во время создания
Само по себе конечно ничего не должно удаляться
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.19, 10:07
ElisDN
SiZE писал(а): ↑2018.04.19, 09:51
Когда создается новая модель поведения автоматически не атачатся (не смотря на то что сказано об этом в мане). attach() вызывается только при инициализации поведений в следствии обращения к несуществующему методу или свойству модели.
В методе BaseActiveRecord::init() при создании вызывается trigger(EVENT_INIT), который запускает ensureBehaviors.
Re: Не добавляется правило валидации в модель через поведение
Добавлено: 2018.04.19, 11:00
SiZE
ElisDN писал(а): ↑2018.04.19, 10:07
В методе BaseActiveRecord::init() при создании вызывается trigger(EVENT_INIT), который запускает ensureBehaviors.
Действительно, спасибо за поправку. Я по коду смотрел, не учел этот момент.