Trigger StatusHashtag observer on deletion to keep cached_count accurate

pull/7154/head
Your Name 2 weeks ago
parent 057648778b
commit 444c796bac

@ -155,7 +155,9 @@ class DeleteAccountPipeline implements ShouldQueue
MediaTag::whereProfileId($id)->delete();
Bookmark::whereProfileId($id)->forceDelete();
EmailVerification::whereUserId($user->id)->forceDelete();
StatusHashtag::whereProfileId($id)->delete();
// Model-based delete so StatusHashtagObserver::deleted() runs and
// decrements hashtags.cached_count (a query-builder delete bypasses it).
StatusHashtag::whereProfileId($id)->get()->each->delete();
DirectMessage::whereFromId($id)->orWhere('to_id', $id)->delete();
Conversation::whereFromId($id)->orWhere('to_id', $id)->delete();
StatusArchived::whereProfileId($id)->delete();

@ -95,7 +95,9 @@ class DeleteRemoteStatusPipeline implements ShouldQueue
});
Mention::whereStatusId($status->id)->forceDelete();
Report::whereObjectType(Status::class)->whereObjectId($status->id)->delete();
StatusHashtag::whereStatusId($status->id)->delete();
// Model-based delete so StatusHashtagObserver::deleted() runs and
// decrements hashtags.cached_count (a query-builder delete bypasses it).
StatusHashtag::whereStatusId($status->id)->get()->each->delete();
StatusView::whereStatusId($status->id)->delete();
Status::whereReblogOfId($status->id)->forceDelete();
$status->forceDelete();

@ -179,7 +179,9 @@ class RemoteStatusDelete implements ShouldBeUniqueUntilProcessing, ShouldQueue
->whereObjectId($status->id)
->delete();
StatusArchived::whereStatusId($status->id)->delete();
StatusHashtag::whereStatusId($status->id)->delete();
// Model-based delete so StatusHashtagObserver::deleted() runs and
// decrements hashtags.cached_count (a query-builder delete bypasses it).
StatusHashtag::whereStatusId($status->id)->get()->each->delete();
StatusView::whereStatusId($status->id)->delete();
Status::whereInReplyToId($status->id)->update(['in_reply_to_id' => null]);

@ -165,7 +165,9 @@ class StatusDelete implements ShouldQueue
->delete();
StatusArchived::whereStatusId($status->id)->delete();
StatusHashtag::whereStatusId($status->id)->delete();
// Model-based delete so StatusHashtagObserver::deleted() runs and
// decrements hashtags.cached_count (a query-builder delete bypasses it).
StatusHashtag::whereStatusId($status->id)->get()->each->delete();
StatusView::whereStatusId($status->id)->delete();
Status::whereInReplyToId($status->id)->update(['in_reply_to_id' => null]);

@ -0,0 +1,52 @@
<?php
use App\Models\Hashtag;
use App\Models\StatusHashtag;
use Illuminate\Foundation\Testing\LazilyRefreshDatabase;
use Illuminate\Support\Facades\Event;
uses(LazilyRefreshDatabase::class);
/*
|--------------------------------------------------------------------------
| StatusHashtag model-delete fires observer
|--------------------------------------------------------------------------
|
| Deleting status_hashtags during status/account deletion must fire the
| eloquent "deleted" event so StatusHashtagObserver decrements
| hashtags.cached_count. A query-builder ->delete() bypasses the event;
| ->get()->each->delete() (the fix) fires it per row.
|
*/
function seedStatusHashtag(): StatusHashtag
{
$hashtag = Hashtag::create(['name' => 'sunset', 'slug' => 'sunset']);
return StatusHashtag::create([
'status_id' => 900000000000000001,
'hashtag_id' => $hashtag->id,
'profile_id' => 123,
'status_visibility' => 'public',
]);
}
it('fires the model deleted event for a model-based delete (the fix)', function () {
seedStatusHashtag();
Event::fake();
StatusHashtag::whereStatusId(900000000000000001)->get()->each->delete();
Event::assertDispatched('eloquent.deleted: '.StatusHashtag::class);
});
it('does not fire the model deleted event for a query-builder delete (the bug)', function () {
seedStatusHashtag();
Event::fake();
StatusHashtag::whereStatusId(900000000000000001)->delete();
Event::assertNotDispatched('eloquent.deleted: '.StatusHashtag::class);
});
Loading…
Cancel
Save