Laravel删除父模型时无法触发子模型deleting事件的解决方法
Fixing Laravel 5.4's Deleting Event Not Firing for Child Models When Deleting Parent
Hey there, let's break down why your ProjectImage model's deleting event isn't firing when you delete a Project—and how to fix it.
Why Your Current Approaches Aren't Working
Let's start with the root causes:
- Database-level cascade delete (
onDelete('cascade')): This is a pure database operation, not an Eloquent one. Laravel never loads theProjectImageinstances, so the model'sdeletingevent (tied to Eloquent's model lifecycle) never gets triggered. $project->images()->delete(): This runs a bulk SQL delete statement directly (DELETE FROM project_images WHERE project_id = ?). Eloquent doesn't load individualProjectImageinstances here, so no events fire for each child model.
The Solution: Delete Child Model Instances Individually
To trigger the deleting event for each ProjectImage, you need to load each child model instance and call delete() on it one by one. Here's how to update your Project model's boot method:
class Project extends Model { protected static function boot() { parent::boot(); static::deleting(function ($project) { // Use the collection (without parentheses) to load all child instances $project->images->each(function ($image) { $image->delete(); // This triggers the ProjectImage's deleting event }); }); } public function images() { return $this->hasMany(ProjectImage::class); } }
Key Notes
- Remove database cascade delete: Make sure you've fully removed the
onDelete('cascade')from your migration—otherwise the database might delete the child records before Eloquent can process the events. - Test with Tinker: As you already know, always restart Tinker after modifying model code (since Tinker caches classes). You can add a quick debug check in your
ProjectImage'sdeletingevent to confirm it's firing:
When you delete aclass ProjectImage extends Model { protected static function boot() { parent::boot(); static::deleting(function ($image) { dd("Deleting event triggered for image ID: {$image->id}"); }); } }Projectin Tinker, you should see this debug message for each associated image.
Performance Consideration
If you have a huge number of child images, deleting them one by one might have minor performance overhead. For most use cases though, this is acceptable—since the tradeoff is getting to run your deleting event logic (like cleaning up stored files, logging, etc.).
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

