You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 the ProjectImage instances, so the model's deleting event (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 individual ProjectImage instances 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's deleting event to confirm it's firing:
    class ProjectImage extends Model
    {
        protected static function boot()
        {
            parent::boot();
    
            static::deleting(function ($image) {
                dd("Deleting event triggered for image ID: {$image->id}");
            });
        }
    }
    
    When you delete a Project in 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:07:29