Yii2 behaviors. Как остановить процесс сохранения модели из поведения?

Есть модель Event, для нее создано поведение, которое сохраняет данные другой модели(EventAttribute).
Если сделать так
public function beforeSave($insert) {
       parent::beforeSave($insert);              
       
        if(!$this->saveEavAttributes()){
            return false;
        }
        return true;
}

и метод $this->saveEavAttributes() возвращает FALSE, меня перекидывает обратно на страницу добавления(редактирования) и выводит допущенные ошибки.

Но если сделать это через метод поведения, так
public function events() {
        return [
            \yii\db\ActiveRecord::EVENT_BEFORE_INSERT => 'saveEavAttributes',
            \yii\db\ActiveRecord::EVENT_BEFORE_UPDATE => 'saveEavAttributes',
        ];
    }

то все обрабатывается типо все успешно, просто не сохраняются ошибочные атрибуты.

Вопрос: как это можно исправить?
  • Вопрос задан
  • 4341 просмотр
Пригласить эксперта
Ответы на вопрос 4
если у вас до beforeSave дошло, значит ошибок валидации быть не должно, и значит все ошибки в saveEavAttributes
Ответ написан
Комментировать
@drwhite87 Автор вопроса
Так и есть
public function saveEavAttributes() {
        $noError = TRUE;
        if (count($this->attributes > 0)) {
            foreach ($this->attributes as $attribute) {
                $attributeModel = $this->getAttributeModel($attribute);

                if (empty($attribute->value)) {
                    if ($attribute->required) {
                        $attribute->addError($this->alias, Yii::t('yii', '{attribute} cannot be blank.', ['attribute' => $attribute->name]));
                        return FALSE;
                    } else {
                        $attributeModel->delete();
                        return;
                    }
                }

                $attributeModel->event_id = $this->owner->id;
                $attributeModel->attribute_id = $attribute->id;
                $attributeModel->value = $this->owner->eavAttributes->{$attribute->alias}->value;
                if (!$attributeModel->save()) {
                    $attribute->addError($attribute->alias, str_replace('Value', $attribute->name, $attributeModel->errors['value'][0]));
                    $noError = FALSE;
                }
            }
        }

        return $noError;
    }


А потом в представление с помощью виджета вывожу ошибки штатными средствами(в представление приходит модель атрибута соответствующего типа).

<div class="form-group field-event-<?= $model->alias ?>">
    <?= \yii\helpers\Html::label($model->name)?>
    <?= \yii\helpers\Html::input('text', $attribute, $model->value, ['class' => 'form-control'])?>
    <div class="has-error"><div class="help-block"><?= \yii\helpers\Html::error($model, $model->alias)?></div></div>
</div>


Как же все таки остановить запрос с ошибкой?
Ответ написан
Комментировать
@lithium_li
Во время вызова метода прицепленного к событию в Behavior::events() в аргумент метода передается объект события:

public function beforeSave($event)
{
     $event->isValid = $this->saveEavAttributes();
}


Значение которое возвращает beforeSave() yii игнорирует, потому возвращать что-то из таких методов в поведении нет смысла.
Ответ написан
Комментировать
Вместо возврата false выбрасывай исключение, лови снаружи и обрабатывай :)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы