2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-03-04 01:15:08 +08:00
discourse/app/models/topic_featured_users.rb
Amanda Alves Branquinho 15e267f791
DEV: Optimize core user merger (#36455)
Co-authored-by: Gerhard Schlager <gerhard.schlager@discourse.org>
2025-12-05 14:45:54 -03:00

104 lines
2.6 KiB
Ruby

# frozen_string_literal: true
class TopicFeaturedUsers
attr_reader :topic
def initialize(topic)
@topic = topic
end
def self.count
4
end
# Chooses which topic users to feature
def choose(args = {})
self.class.ensure_consistency!(topic.id.to_i)
update_participant_count
end
def user_ids
[
topic.featured_user1_id,
topic.featured_user2_id,
topic.featured_user3_id,
topic.featured_user4_id,
].uniq.compact
end
def self.ensure_consistency!(topic_id = nil)
filter = "#{"AND t.id = #{topic_id.to_i}" if topic_id}"
filter2 = "#{"AND tt.id = #{topic_id.to_i}" if topic_id}"
sql = <<SQL
WITH cte as (
SELECT
t.id,
p.user_id,
MAX(p.created_at) last_post_date,
ROW_NUMBER() OVER(PARTITION BY t.id ORDER BY COUNT(*) DESC, MAX(p.created_at) DESC) as rank
FROM topics t
JOIN posts p ON p.topic_id = t.id
WHERE p.deleted_at IS NULL AND
NOT p.hidden AND
p.post_type in (#{Topic.visible_post_types.join(",")}) AND
p.user_id <> t.user_id AND
p.user_id <> t.last_post_user_id
#{filter}
GROUP BY t.id, p.user_id
),
cte2 as (
SELECT id, user_id, ROW_NUMBER() OVER(PARTITION BY id ORDER BY last_post_date ASC) as rank
FROM cte
WHERE rank <= #{count}
)
UPDATE topics tt
SET
featured_user1_id = x.featured_user1,
featured_user2_id = x.featured_user2,
featured_user3_id = x.featured_user3,
featured_user4_id = x.featured_user4
FROM topics AS tt2
LEFT OUTER JOIN (
SELECT
c.id,
MAX(case when c.rank = 1 then c.user_id end) featured_user1,
MAX(case when c.rank = 2 then c.user_id end) featured_user2,
MAX(case when c.rank = 3 then c.user_id end) featured_user3,
MAX(case when c.rank = 4 then c.user_id end) featured_user4
FROM cte2 as c
GROUP BY c.id
) x ON x.id = tt2.id
WHERE tt.id = tt2.id AND
(
COALESCE(tt.featured_user1_id,-99) <> COALESCE(x.featured_user1,-99) OR
COALESCE(tt.featured_user2_id,-99) <> COALESCE(x.featured_user2,-99) OR
COALESCE(tt.featured_user3_id,-99) <> COALESCE(x.featured_user3,-99) OR
COALESCE(tt.featured_user4_id,-99) <> COALESCE(x.featured_user4,-99)
)
#{filter2}
SQL
DB.exec(sql)
end
private
def update_participant_count
DB.exec(<<~SQL, topic_id: topic.id)
UPDATE topics
SET participant_count = (
SELECT COUNT(DISTINCT user_id)
FROM posts
WHERE topic_id = :topic_id
AND NOT hidden
AND post_type IN (#{Topic.visible_post_types.join(",")})
AND deleted_at IS NULL
)
WHERE id = :topic_id
SQL
end
end