Why You Might Want to Hydrate Models to Delete Them in Laravel

Oct 15, 2025 laravel
Context: Laravel 12

There are many ways to handle cascading functionality in Laravel. You can do this with observers, events, manually dispatched jobs - even in MySQL with cascading deletes.

I prefer to keep my cascading logic in the application code by using Eloquent Model Events. This is super easy when it’s just a single level of model. But what about relationships?

So let’s talk about a car with parking reservations. When our Car model gets deleted, we want to delete all of the parking reservations as well.

I’m going to register an event right in the booted method of the Eloquent model.

protected static function booted(): void
{
  static::deleting(fn (self $self) => $self->reservations->each->delete());
}

Now, whenever a Car is deleted, all of its reservations (through the ->reservations() HasMany relationship) are deleted.

But wait a second - this is doing some sort of loop on the loaded relationship! If it was doing it completely in the database, the command would look like $self->reservations()->delete() - but this is retrieving all and looping over them.

Why?

Because I have introduced a cascading pattern into the project - so my assumption is that any time I define a cascading functionality it is now in effect. If we didn’t retrieve each of the Reservation model, then any of those deleting events on those reservations will never be called. Maybe there is more cleanup?

This is not a great idea for every solution (imagine a situation where there are 1000s of records) - but in general, when there are a limited amount - I find the ‘cost’ of retrieving and hydrating these models to be a lot less than the built in functionality / ability to never forget to consider the whole hierarchy. I just have to focus on one model at a time.

Looking for more Laravel Tips & Tricks? Join Joel and I on the No Compromises bi-weekly podcast; around 15 minutes of thoughtful real-world advice and helpful info.
Go to All Posts