Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel - how to delete polymorphic relations of model with belongsTo relation?

Tags:

php

laravel

I have 4 tables. Two of them are monomorphic and two of them are polymorphic.

Monomorphic: Templates, Modules

Polymorphic: Documents, Images

Now, templates and modules have both documents and images and each Template has many Modules and modules have foreign key that is set to cascade on deletion of templates.

Now, if I delete a Template the associated Modules will be deleted but the associated polymorphic relations of Module will stay in Database. I haven't tried anything because I am completely clueless.

Anything I could do to automatically delete associations of Module when Template is deleted? I think the deletion here in this is being handled by Database itself and Eloquent doesn't have anything to do with it.

like image 1000
Muhammad Talha Akbar Avatar asked Mar 10 '23 07:03

Muhammad Talha Akbar


2 Answers

Because it is a polymorphic relationship, the cascading delete cannot be handled by a foreign key.

If you still want the deletes to be handled at the database level, you will need to write some type of database trigger functionality.

There are also a couple options if you want to handle this at the application level.

One option is to update your code so that everywhere you delete your Template, you also make sure to delete all of it's polymorphic relations.

Another option would be to create an event handler for the deleting event. The deleting event is fired by Eloquent whenever you delete an Eloquent model. Inside this deleting event, you can access the polymorphic relationship and delete them, as well.

If the deleting event method sounds okay, there is a package that implements all of this for you, and makes it very easy to setup for your models: shiftonelabs/laravel-cascade-deletes. Full disclosure: I wrote the package.

With this package, you just add the CascadesDeletes trait to your Template model, and then add a $cascadeDeletes property that contains an array of all the relationships to delete when a Template instance is deleted.

like image 148
patricus Avatar answered Apr 27 '23 00:04

patricus


It's not fully automatic, but I handle it very easy with the destroy() Eloquent method. https://laravel.com/docs/8.x/eloquent#deleting-an-existing-model-by-key In addition, when you will use it with Laravel Queues, it works like a charm...

Example:

$template = Template::find(1);

Module::destroy($template->modules);

$template->delete();
like image 23
Jakub Adamec Avatar answered Apr 27 '23 02:04

Jakub Adamec