In a hasMany
relationship, what should happen with the children's record if you delete the parent record? I will show you three ways how to deal with that situation.
Here are our options:
- Validation on the Laravel level: How can that error be processed more gracefully?
- Validation on DB level: in Laravel migrations.
- Using soft-deletes instead of deleting anything.
Laravel Project
First, the project setup and the problem itself.
In the project, we have two Models: Company and Contact. A contact belongs to a company.
database/migrations/xxx_create_companies_table.php:
Schema::create('companies', function (Blueprint $table) { $table->id(); $table->string('company_name'); $table->string('company_address'); $table->string('company_website'); $table->string('company_email'); $table->timestamps();});
database/migrations/xxx_create_contacts_table.php:
Schema::create('contacts', function (Blueprint $table) { $table->id(); $table->foreignId('company_id')->constrained(); $table->string('contact_name'); $table->string('contact_last_name'); $table->string('contact_phone_1'); $table->string('contact_phone_2'); $table->string('contact_email'); $table->string('contact_skype'); $table->string('contact_address'); $table->timestamps();});
To delete a company in the Controller, simply call the delete()
method on the Company
Model, which comes from the Route Model Binding.
use App\Models\Company;use Illuminate\Http\RedirectResponse; class ContactCompanyController extends Controller{ // ... public function destroy(Company $contactCompany): RedirectResponse { $contactCompany->delete(); return redirect()->back(); }}
When the delete method is executed without any additional checks, the Integrity constraint violation
error is shown.
Now, what are our options to solve it?
Option 1: Laravel Validation on Delete
Let's validate if the company has children of contacts. If it does, do not allow deleting them. There are a few ways to do that, but the most straightforward is adding an...