I have this model that uses a static boot for deleting related models/tables in the db. First is the product model.
protected static function boot() {
parent::boot();
static::deleting(function($product) {
$product->hearts()->delete();
$product->comments()->delete();
});
}
It deletes the hearts and comments and it's working like a charm. But the problem is I have this reply model that has an relationship with my comment model and that reply model is being referenced from the comment model
public function replies()
{
return $this->hasMany("App\Reply");
}
Then in my comment model I used another static boot for "Chaining" the boot delete from the product
protected static function boot() {
parent::boot();
static::deleting(function($comment) {
$comment->replies()->delete();
});
}
but it's not working. Can you guys give me an insight why this isn't working? Logically it should work because the comment is being deleted. Thank you.
Inside your first deleting
event, you are calling $product->comments()->delete();
. This line is actually calling the delete()
method on a query builder object, and not the Comment
models. Because no Comment
models are created during the delete, the deleting
event on the Comment
will not be executed.
In order do to this type of application level cascading deletes, you will need to make sure that delete is only ever called on Comment
instances. You an either loop through the related records and delete them, or get a list of their ids and use the destroy()
method (which does a loop behind the scenes):
// do a loop yourself
static::deleting(function($product) {
foreach ($product->comments as $comment) {
$comment->delete();
}
});
// or, destroy all the ids
static::deleting(function($product) {
$ids = $product->comments()->lists('id')->all();
Comment::destroy($ids);
});
Having said all that, if you have simple relationships and access to modify the database, you'll probably want to setup database level cascading deletes. This will be much faster than application level cascading deletes, as you won't need to load every model for every record to delete.
However, if you're in a situation where you need application level cascading deletes (e.g. polymorphic relationships, application architect requires them, etc), I do have a package that takes care of this for you: shiftonelabs/laravel-cascade-deletes. You just add a trait to your model and define the array of relationships to cascade delete, and you don't need to worry about anything else.
This is working for me
static::deleting(function($product) {
$product->comments->each->delete()
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With