#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
класс исключений.