CASCADING ACTIONS WITHIN TRANSACTIONS
Mar 07, 2024 Copy Link
You should be careful when deleting a model instance somehow related to another model to ensure enough that both model instances were successfully deleted, otherwise, roll back whole actions and try to execute them again!
Let's complete that Tip but we will assume the opposite and remove the parent user after the car has been deleted. Presume that while we delete the car, an exception is triggered from the user for whatever reason, so the action that must be taken is the car must be rollbacked...Yeah, we're talking about the database transactions
In the first instance, Let's prepare the exception in `Car.php`
the model class that will hinder the deletion process:
// \App\Models\Car.php
public static function boot()
{
parent::boot();
static::deleted(function ($car) {
throw new Exception("Cascading Delete Fails");
$car->user()->delete();
});
}
Now let's figure out how Laravel configures the transactions that are responsible for rolling back:
use App\Models\Car; use Illuminate\Support\Facades\DB;
try {
DB::beginTransaction();
Car::first()->delete(); DB::commit();
} catch (\Throwable $th) {
DB::rollBack();
}
If you have executed the previous code you will recognize that nothing happened and the car will not be removed 👣
Also, Laravel ships with a more convenient way that begins the transaction and then commits it if successfully executed, otherwise, it will be rollbacked, in just one single line:
use App\Models\Car;
use Illuminate\Support\Facades\DB;
try {
DB::transaction(fn () => Car::first()->delete());
} catch (\Throwable $th) {
//
}
Without wrapping the car deletion line with the transaction, the car will be deleted and its parent user will still be presented in the database useless.