From 300db3d3fa635ef8e132123e1d96e380946f6cc1 Mon Sep 17 00:00:00 2001 From: Bianca Nenciu Date: Thu, 29 Jul 2021 17:06:11 +0300 Subject: [PATCH] FIX: Update draft count after creating a post (#13884) When a post is created, the draft sequence is increased and then older drafts are automatically executing a raw SQL query. This skipped the Draft model callbacks and did not update user's draft count. I fixed another problem related to a raw SQL query from Draft.cleanup! method. --- app/models/draft.rb | 2 ++ app/models/user_stat.rb | 37 +++++++++++++++++++--------- lib/post_creator.rb | 1 + spec/components/post_creator_spec.rb | 8 ++++-- spec/models/draft_spec.rb | 2 ++ 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/app/models/draft.rb b/app/models/draft.rb index 7b39d44e9a0..924c987edcf 100644 --- a/app/models/draft.rb +++ b/app/models/draft.rb @@ -254,6 +254,8 @@ class Draft < ActiveRecord::Base # remove old drafts delete_drafts_older_than_n_days = SiteSetting.delete_drafts_older_than_n_days.days.ago Draft.where("updated_at < ?", delete_drafts_older_than_n_days).destroy_all + + UserStat.update_draft_count end def self.backup_draft(user, key, sequence, data) diff --git a/app/models/user_stat.rb b/app/models/user_stat.rb index 69bc63a5735..045dcaca703 100644 --- a/app/models/user_stat.rb +++ b/app/models/user_stat.rb @@ -202,19 +202,32 @@ class UserStat < ActiveRecord::Base self.class.update_distinct_badge_count(self.user_id) end - def self.update_draft_count(user_id) - draft_count = DB.query_single <<~SQL, user_id: user_id - UPDATE user_stats - SET draft_count = (SELECT COUNT(*) FROM drafts WHERE user_id = :user_id) - WHERE user_id = :user_id - RETURNING draft_count - SQL + def self.update_draft_count(user_id = nil) + if user_id.present? + draft_count = DB.query_single <<~SQL, user_id: user_id + UPDATE user_stats + SET draft_count = (SELECT COUNT(*) FROM drafts WHERE user_id = :user_id) + WHERE user_id = :user_id + RETURNING draft_count + SQL - MessageBus.publish( - '/user', - { draft_count: draft_count.first }, - user_ids: [user_id] - ) + MessageBus.publish( + '/user', + { draft_count: draft_count.first }, + user_ids: [user_id] + ) + else + DB.exec <<~SQL + UPDATE user_stats + SET draft_count = new_user_stats.draft_count + FROM (SELECT user_stats.user_id, COUNT(drafts.id) draft_count + FROM user_stats + LEFT JOIN drafts ON user_stats.user_id = drafts.user_id + GROUP BY user_stats.user_id) new_user_stats + WHERE user_stats.user_id = new_user_stats.user_id + AND user_stats.draft_count <> new_user_stats.draft_count + SQL + end end # topic_reply_count is a count of posts in other users' topics diff --git a/lib/post_creator.rb b/lib/post_creator.rb index 69a94bdc806..922c7e39c24 100644 --- a/lib/post_creator.rb +++ b/lib/post_creator.rb @@ -229,6 +229,7 @@ class PostCreator @post.topic.reload publish + UserStat.update_draft_count(@user.id) track_latest_on_category enqueue_jobs unless @opts[:skip_jobs] diff --git a/spec/components/post_creator_spec.rb b/spec/components/post_creator_spec.rb index f7d1c096b7d..368ba3bf157 100644 --- a/spec/components/post_creator_spec.rb +++ b/spec/components/post_creator_spec.rb @@ -165,7 +165,9 @@ describe PostCreator do "/latest", "/latest", "/topic/#{created_post.topic_id}", - "/topic/#{created_post.topic_id}" + "/topic/#{created_post.topic_id}", + "/user", + "/user" ].sort ) @@ -194,7 +196,7 @@ describe PostCreator do user_action = messages.find { |m| m.channel == "/u/#{p.user.username}" } expect(user_action).not_to eq(nil) - expect(messages.filter { |m| m.channel != "/distributed_hash" }.length).to eq(5) + expect(messages.filter { |m| m.channel != "/distributed_hash" }.length).to eq(6) end it 'extracts links from the post' do @@ -281,12 +283,14 @@ describe PostCreator do it 'creates post stats' do Draft.set(user, Draft::NEW_TOPIC, 0, "test") Draft.set(user, Draft::NEW_TOPIC, 0, "test1") + expect(user.user_stat.draft_count).to eq(1) begin PostCreator.track_post_stats = true post = creator.create expect(post.post_stat.typing_duration_msecs).to eq(0) expect(post.post_stat.drafts_saved).to eq(2) + expect(user.reload.user_stat.draft_count).to eq(0) ensure PostCreator.track_post_stats = false end diff --git a/spec/models/draft_spec.rb b/spec/models/draft_spec.rb index 54218c5e9eb..0e4dc72bf52 100644 --- a/spec/models/draft_spec.rb +++ b/spec/models/draft_spec.rb @@ -152,6 +152,7 @@ describe Draft do Draft.set(user, key, 0, 'draft') Draft.cleanup! expect(Draft.count).to eq 1 + expect(user.user_stat.draft_count).to eq(1) seq = DraftSequence.next!(user, key) @@ -161,6 +162,7 @@ describe Draft do Draft.cleanup! expect(Draft.count).to eq 0 + expect(user.reload.user_stat.draft_count).to eq(0) Draft.set(Fabricate(:user), Draft::NEW_TOPIC, 0, 'draft')