Yii2: Могу ли я создавать правила и пользовательские сообщения об ошибках, которые применяются при УДАЛЕНИИ модели?

#php #yii2 #delete-row #yii2-model

#php #yii2 #удалить строку #yii2-модель

Вопрос:

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

Как только я определю свои сообщения об ошибках, как я могу наилучшим образом сохранить их и передать интерфейсу? beforeDelete() возвращает только true или false, но мне, конечно, нужно предоставить пользователю понятные сообщения об ошибках, объясняющие, ПОЧЕМУ запись не может быть удалена…

Уже определенная связь, например:

 public function getPhonenumbers() {
    return $this->hasMany(Phonenumber::class, ['ph_contactID' => 'contactID']);
}
  

Комментарии:

1. пожалуйста, укажите ваш actionDelete() код.

2. Может потребоваться проверка транзакций? yiiframework.com/doc/api/2.0/yii-db-transaction

Ответ №1:

Из ответов @vishuB и @rob006 у меня появились идеи по созданию собственного решения, которое, я думаю, будет превосходным, поскольку я могу предоставлять несколько сообщений об ошибках, его также можно использовать в API, и оно не зависит от исключений try / catching:

 public function beforeDelete() {
    if (!parent::beforeDelete()) {
        $this->addError('contactID', 'For some unknown reason we could not delete this record.');
    }

    if (!empty($this->phonenumbers)) {
        $this->addError('contactID', 'Contact is linked to a used phone number and cannot be deleted.');
    }

    if ($some_other_validation_fails) {
        $this->addError('contactID', 'Contact cannot be deleted because it is more than two months old.');
    }

    return ($this->hasErrors() ? false : true);
}
  

Затем в моем действии я делаю это:

 $contact = Contact::findOne($contactID);
if (!$contact->delete()) {
    return $contact->getErrors();  //or use flash messages and redirect to page if you prefer
}
return true;
  

Ответ №2:

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

 public function beforeDelete() {
    if ($this->getPhonenumbers()->exist()) {
        throw new DeleteFailException('Records with phone numbers cannot be deleted.');
    }

    return parent::beforeDelete();
}
  

И в действии контроллера:

 try {
    $model->delete();
} catch (DeleteFailException $esception) {
    Yii::$app->session->setFlash('error', $exception->getMessage());
}
  

Комментарии:

1. Однако сначала нужно было бы определить DeleteFailException класс исключений.