tags: fix post counts for nonexistent tags.

Fix a bug where the post count regenerator didn't fix counts for tags
that had a non-zero count but weren't present on any posts.
This commit is contained in:
evazion
2019-12-27 11:19:13 -06:00
parent b6a3a05422
commit 3b4f9ad086
2 changed files with 31 additions and 8 deletions

View File

@@ -106,23 +106,43 @@ class Tag < ApplicationRecord
Tag.where(name: tag_names).update_all("post_count = post_count - 1")
end
def regenerate_post_counts!
sql = <<~SQL
# fix tags where the post count is non-zero but the tag isn't present on any posts.
def regenerate_nonexistent_post_counts!
Tag.find_by_sql(<<~SQL)
UPDATE tags
SET post_count = COALESCE(true_count, 0)
SET post_count = 0
WHERE
post_count != 0
AND name NOT IN (
SELECT DISTINCT tag
FROM posts, unnest(string_to_array(tag_string, ' ')) AS tag
GROUP BY tag
)
RETURNING tags.*
SQL
end
# fix tags where the stored post count doesn't match the true post count.
def regenerate_incorrect_post_counts!
Tag.find_by_sql(<<~SQL)
UPDATE tags
SET post_count = true_count
FROM (
SELECT tag, COUNT(*) AS true_count
FROM posts, unnest(string_to_array(tag_string, ' ')) AS tag
GROUP BY tag
) true_counts
WHERE
(tags.name = tag AND tags.post_count != true_count)
OR tags.post_count < 0
tags.name = tag AND tags.post_count != true_count
RETURNING tags.*
SQL
end
updated_tags = Tag.find_by_sql(sql)
updated_tags
def regenerate_post_counts!
tags = []
tags += regenerate_incorrect_post_counts!
tags += regenerate_nonexistent_post_counts!
tags
end
end
end

View File

@@ -278,11 +278,14 @@ class TagTest < ActiveSupport::TestCase
should "be fixed" do
tag1 = FactoryBot.create(:tag, name: "touhou", post_count: -10)
tag2 = FactoryBot.create(:tag, name: "bkub", post_count: 10)
tag3 = FactoryBot.create(:tag, name: "chen", post_count: 10)
post = FactoryBot.create(:post, tag_string: "touhou bkub")
Tag.regenerate_post_counts!
tags = Tag.regenerate_post_counts!
assert_equal(3, tags.size)
assert_equal(1, tag1.reload.post_count)
assert_equal(1, tag2.reload.post_count)
assert_equal(0, tag3.reload.post_count)
end
end
end