-
-
Save niallobrien/5091363 to your computer and use it in GitHub Desktop.
<?php | |
// I have Groups. A group can have many discussions. A single discussion can have many posts. | |
// models/Group.php | |
public function delete() | |
{ | |
// Check for discussions belonging to the group first | |
if ($this->discussions) { | |
foreach ($this->discussions as $discussion) { | |
$discussion->delete(); | |
} | |
} | |
// Remove entry in group_user pivot table | |
$this->users()->delete(); | |
// Now delete the group | |
return parent::delete(); | |
} | |
// models/Discussion.php | |
function delete() | |
{ | |
// Check for posts to discussion first | |
if ($this->posts) { | |
foreach ($this->posts as $post) { | |
$post->delete(); | |
} | |
} | |
// Now delete the discussion | |
return parent::delete(); | |
} | |
// The Post model does pretty much the same as the Discussion model. |
I think that this can be improved significantly. Instead of deleting each line individually, rather gather all the ID's for deletion, and pass through one delete:
$ids = array();
if ($this->discussions) {
foreach ($this->discussions as $discussion) {
$ids[] = $discussion->id;
}
}
if (count($ids) > 0) {
Discussion::whereIn($ids)->delete();
}
Always be aware of the number of queries hitting your db.
Awesome improvement, thanks!
If you're using the new soft-delete feature in L4, and want to cascade hard-delete models, including models already soft-deleted, modify your foreach loop to include withTrashed() models.
foreach ($this->discussions()->withTrashed()->get() as $discussion) {
$discussion->forceDelete();
}
Thank you very much for this gist. It's been very helpful. Thanks!
Teaching myself Laravel and new here. But there are two things I'd like to point out to JonoB (Please correct me if I'm wrong!)
"Discussion::whereIn($ids)->delete();" is missing a parameter in the whereIn() clause. (Field name)
i.e. "Discussion::whereIn('id', $ids)->delete();"
and
Using your method to bulk delete in one query does not cascade down to other models delete() method on related objects.
i.e. If Discussion also contains cascade deletes in the model they will not execute.
First, I wrote the delete method for the last child of the cascade (Post model). Then worked my way up the chain and they each called the child deletes. So the Group model loops through all discussions on that group, calls the delete method on each discussion and that calls the delete method on each post within that discussion. Finally it then deletes the group.