Laravel HasMany: Delete Parent - What Happens with Children?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello guys today we're gonna be talking about the error that you see on the screen soin has many relationships if you delete the parents record what should happen with children record and in this video I will show you three ways how to deal with that situation first in laravel validation so how to process that error more gracefully second is an laravel migrations so process that on database level in table structure or in foreign key structure and finally by using soft deletes and not actually deleting anything so let's go the situation demo project partly based on our quick admin panel contact management module and there is a company and there is a contact and contact belongs to a company so it is a has many relationship one-to-many and in the database we have this contacts with company ID and companies just a simple table no soft deletes and deleting is happening in a simple way like this destroy method permission check and then deleting the company no more conditions and when we click the companies and delete of course we see that error so first let's take care of that in laravel validation so let's validate if the company has children of contacts do not allow to delete that and there are a few ways to do that but probably the most straightforward is here in the destroy method we can just add if statements so if contact company contacts which has many relationship count then we return back back with errors and then let's try to delete again exactly what was expected cannot delete company has contact records and that error by the way doesn't come automatically it comes from our quick admin panel generated code in blade so like this so if there are errors we show them like this so you would need to add that code something like that in your blade files so that's one way to prevent the deleting the parent but maybe we should restrict it on the front end so in this case if we know that company has contact records who should it even the delete button right and we can do that but then in index we need to load the company with the relationship get and with contacts right and then in index blade index blade where we have delete button delete form we would need to check if company contacts account if like this if not if there's no contact then we show the button and I'll refresh the page and as you can see no button and to test it out let's add another company with foreign filler Chrome extension and new company has that button which means they don't have any records but with this method I'm not entirely sure it's good because first thing you still need to validate that on the back end because you cannot trust front and validation at any time it's just for UX purposes and other things it adds quite a lot of performance issues in controller you have to load more relationships for all the records and if it's just one record it's cool but if there are more records inside of that company what if there are transactions employees documents whatever and you would have to check all of them while loading the table and 99% of the users won't ever delete anything so you are loading a lot of data for 1% of the customer so instead of that in my personal opinion it's better to check on the deleting record just in here put the back-end validation on the front-end delete button can stay visible without any check okay so we've covered the first part how to gracefully handle the default behavior or restricting the deleting now what if we want to change that default behavior and how can we do that for that we need to check the mysql documentation I will talk about MySQL database so check your database if you're working with something else but when creating foreign keys you can specify on delete action in migrations we have something like this so when creating foreign key in here we can add on delete statement and on delete by default in my is no action which is the same as restrict so there are options basically there are three options there are more but the main ones actually used and actually logical are restrict which is happening right now so if we are deleting the parent restrict comes from minus 2l and shows that error that we've seen before so that's a restrict what we can do also is cascade which means that all the parent record that are deleted will also delete the child records with them so cascading and third option is SEP no which means that all the child records will get no in that field of foreign IT and let's try both of them so in migrations we would add on delete cascade and let's remind grate all the database migrate fresh - - seed now let's remove the validation that we just added so we don't need this anymore and we don't need in the glade anymore so delete that line and that line and behind the scenes I've added one company and one contact and let's click delete button and remember we added cascade as a rule no company and no contact and if we check the database refresh company empty contacts empty so the rule cascade will delete all the children entries and because of that we have to be really careful and tell that to the customer so your message and index blade to delete should be not only are you sure so we have that on submit return confirm are you sure that comes from the translations but you should do something like something like that so people would totally understand that they are deleting all the records including child records so that's cascade other option is set null so if we change that to set no see what happens let's receive the data again again I've added one company in one contact and in the database if we refresh the contacts see filled company ID equals one and it would delete that company click delete no company but there is a contact so the contact the child record stays but without the company if it is knowable of course that field should be notable and if we refresh the table again we would see that company ID is null so to recap this part of the video the section we have three options how to deal with that parent deleting leave it with restrict but then add the validation to show the error message properly not minus QL or we can cascade but then we need to notify the user that we actually were actually deleting the child records or certain oh then child records just leave hanging in the air and they are not attached to anything another popular way of dealing with all of that is soft deletes and they are really easy to add and wearable so let's add them to our both tables so I've added soft deletes in immigration of companies of contacts and then in both models we add use soft leads and use soft leads that's it we migrate the database and I've added again one contact for one company and let's see what happens now if we click delete no error we have no company and contact it's left without company but now let's take a look at the database contact is here and company ID is still one so it's not set to no but the company doesn't exist anymore so company is soft deleted but the child record actually stays in the database and you would think why is it not set to no although we did set that to know in the contacts table in here right because when using soft deletes you are not actually deleting the record you are not telling MySQL to delete the record that's why foreign key rules are not applied you are performing laravel operation of making it soft deleted but all the records stay in the database so you could see that with soft deletes set null is actually a default action it's not literally setting that to no but since parent record is soft deleted it won't be found in the database by default and if you want to change that behavior from said no to restrict or to cascade with restrict is totally the same thing you would just check in the delete here in the destroy method if there are any child records and that restrict that or hide the button if you want so that's totally the same as the first part of the video but now with cascade it's different it's not enough to add on delete cascade that wouldn't work because as I said it doesn't hit the database for cascading of soft deletes there are packages specific laravel packages and I've written about that have an article on our quick admin panel blog about actually deleting the one-to-many relationships and there is one point about cascading soft deletes and there is a package which is really easy to use actually you just require the package specify what relationships to delete with the parent and then it's soft deletes all the children records as well so it's performing cascade but in a soft delete way and there is another package which I haven't tried but it's the same but with polymorphic relationships so if you know parlor morphic relationships doesn't have actually relationships in the database so on MySQL level you cannot delete that with cascade so this packet would help you so this example you have morphs many addresses in profile model and then you provide that you should cascade delete the addresses whenever profile is deleted so to recap the soft deleted part of this video by default soft deleted records work in certain Norway if you want to restrict the deleting part you need to add validation or if you want to cascade then there are two packages I've just showed you that can help you with that hope it was helpful if you want me to continue shooting videos like this one you can support this channel by doing one of two things and roll in one of my courses on teachable the link is on the screen or use our laravel quick admin panel generates or full level admin panel the link is also on the screen and see you guys in other videos
Info
Channel: Laravel Daily
Views: 12,553
Rating: undefined out of 5
Keywords:
Id: Saasvte-BSc
Channel Id: undefined
Length: 10min 51sec (651 seconds)
Published: Mon May 04 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.