在 laravel 中删除行时删除所有关系

Delete all relation when Deleting a row in laravel

我有 Post 评论和通知 Table

每个 Post 有很多评论

每条评论都有许多通知

每个 Post 有许多通知

class Post extends Model
{

    public function notifications() {
        return $this->morphOne(Notification::class, 'to');
    }

    public function comments() {
        return $this->hasMany(Comment::class, 'post_id');
    }

    public static function boot() {
        parent::boot();

        static::deleting(function($post) {
            $post->comments()->delete();
            $post->notifications()->delete();
        });
    } 
}
class Comment extends Model
{
    public function notifications() {
        return $this->morphOne(Notification::class, 'to');
    }

    public static function boot() {
        parent::boot();

        static::deleting(function($comment) {
            $comment->notifications()->delete();
        });
    }
}

当我删除 post 我应该删除通知和评论, 但问题是当我删除评论时,通知并没有被删除, 它们被删除当我直接删除评论但我需要删除评论通知当我删除post!

链接将不起作用,因为模型未初始化。
最好的解决方案是循环并删除个别评论

static::deleting(function($post) {
    foreach ($post->comments() as $comment){
        $comment->delete();
    }
});
static::deleting(function($comment) {
    $ids = $comment->notifications()->lists('id')->all();
    Notification::destroy($ids);
});

Laravel不会实例化它删除的相关模型,这就是为什么当你直接删除评论时通知会被删除,而删除评论删除post时不会删除通知。删除 post 时必须实例化注释才能使其正常工作。

class Post extends Model {
    
    public function notifications() {
        return $this->morphOne(Notification::class, 'to');
    }
    
    public function comments() {
        return $this->hasMany(Comment::class, 'post_id');
    }
    
    public static function boot() {
        parent::boot();
    
        static::deleting(function($post) {
            // here you could instantiate each related Comment
            // in this way the boot function in the Comment model will be called
            $post->comments->each(function($comment) {
                // and then the static::deleting method when you delete each one
                $comment->delete();
            });
            $post->notifications()->delete();
        });
    } 
}

仅作记录,我在评论中添加我们讨论的内容,因为它可以为遇到相同问题的其他人服务,并且在评论中可以不被注意。感谢 OP @Mahmoud Ben Jabir。

But if the post has 100 comments It will execute 100 query to delete them ! I will Figure out how to delete with minimum queries...

I already have onDelete on comments, but the notifications are polymorphic so it won't work on them...

The solution I will use is:
1- Get Ids of Comments that are related to the Post.
2- Delete from Notifications where type IS Comment AND id in (ids).
3- Delete Comments related to the Post.
4- Delete The Notifications Related to the Post
5- Delete The Post.

public static function boot() {
    parent::boot();
    static::deleting(function($post) {
        // 1- Get Ids of Comments that are related to the Post. 
        $ids = $post->comments()->pluck('id'); 
        // 2- Delete from Notifications where type IS Comment AND id in (ids). 
        Notification::where('entity_type', 'App\Comment')->whereIn('entity_id', $ids)->delete(); 
        // 3- Delete Comments related to the Post. 
        $post->comments()->delete();
        // 4- Delete The Notifications Related to the Post 
        $post->notifications()->delete();
    });
    // 5- Delete The Post.
}

请使用(假设post和评论有关系)

$table->foreign('post_id')
      ->references('id')->on('posts')
      ->onDelete('cascade');

在您的迁移文件中建立外国关系。那么当你删除相关的 post 时,它的评论也会被删除。