在 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 时,它的评论也会被删除。
我有 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 时,它的评论也会被删除。