Reputation: 3640
I want to delete a model but it might have related records in another model when will prohibit me doing so. How can I best use the already defined relationships to check if delete will be successful? Potentially there could also be non-relationship reasons for not allowing a delete.
Once I have determined my error messages how can I best store them and pass them on to the front-end? beforeDelete()
only returns true or false but I of course need to provide user with friendly error messages saying WHY the record can't be deleted...
Relationship already defined is for example:
public function getPhonenumbers() {
return $this->hasMany(Phonenumber::class, ['ph_contactID' => 'contactID']);
}
Upvotes: 1
Views: 975
Reputation: 22174
You can throw exception in beforeDelete()
with error message, and catch it in controller.
public function beforeDelete() {
if ($this->getPhonenumbers()->exist()) {
throw new DeleteFailException('Records with phone numbers cannot be deleted.');
}
return parent::beforeDelete();
}
And in controller action:
try {
$model->delete();
} catch (DeleteFailException $esception) {
Yii::$app->session->setFlash('error', $exception->getMessage());
}
Upvotes: 1
Reputation: 3640
From the answers of @vishuB and @rob006 I got ideas for coming up with my own solution which I think will be superior as I can provide multiple error messages, it can be used in an API as well, and it doesn't rely on try/catching exceptions:
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);
}
Then in my action I do this:
$contact = Contact::findOne($contactID);
if (!$contact->delete()) {
return $contact->getErrors(); //or use flash messages and redirect to page if you prefer
}
return true;
Upvotes: 1