FIX: Make sure featured category topics are unique (#18343)

In the past, CategoryFeaturedTopic.feature_topics raised an exception
sometimes because it tried to create multiple CategoryFeaturedTopic
records for the same topic.

This code should not raise any exceptions as long as the list of new
topic IDs is unique because all previous records are deleted first,
then recreated and everything happens inside a transaction. The previous
rescue block was dead code anyway because it tried to catch
PG::UniqueViolation instead of ActiveRecord::RecordNotUnique. This
commit includes a fix to ensure that the topic IDs are unique.
This commit is contained in:
Bianca Nenciu 2022-09-27 14:01:22 +03:00 committed by GitHub
parent be184afc0c
commit 20a17f248c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -60,24 +60,19 @@ class CategoryFeaturedTopic < ActiveRecord::Base
# Add topics, even if they're in secured categories or invisible
query = TopicQuery.new(Discourse.system_user, query_opts)
results = query.list_category_topic_ids(c).uniq
results = query.list_category_topic_ids(c)
# Add some topics that are visible to everyone:
anon_query = TopicQuery.new(nil, query_opts.merge(except_topic_ids: [c.topic_id] + results))
results += anon_query.list_category_topic_ids(c).uniq
results += anon_query.list_category_topic_ids(c)
results.uniq!
return if results == existing
CategoryFeaturedTopic.transaction do
CategoryFeaturedTopic.where(category_id: c.id).delete_all
if results
results.each_with_index do |topic_id, idx|
begin
c.category_featured_topics.create(topic_id: topic_id, rank: idx)
rescue PG::UniqueViolation
# If another process features this topic, just ignore it
end
end
results.each_with_index do |topic_id, idx|
c.category_featured_topics.create(topic_id: topic_id, rank: idx)
end
end
end