100 lines
2.5 KiB
Ruby
100 lines
2.5 KiB
Ruby
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={})
|
|
clear
|
|
update keys(args)
|
|
update_participant_count
|
|
topic.save
|
|
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!
|
|
|
|
sql = <<SQL
|
|
|
|
WITH cte as (
|
|
SELECT
|
|
t.id, p.user_id,
|
|
ROW_NUMBER() OVER(PARTITION BY t.id ORDER BY COUNT(*) 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.user_id <> t.user_id AND
|
|
p.user_id <> t.last_post_user_id
|
|
GROUP BY t.id, p.user_id
|
|
)
|
|
|
|
UPDATE topics tt
|
|
SET
|
|
featured_user1_id = featured_user1,
|
|
featured_user2_id = featured_user2,
|
|
featured_user3_id = featured_user3,
|
|
featured_user4_id = featured_user4
|
|
FROM (
|
|
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 cte as c
|
|
WHERE c.rank <= 4
|
|
GROUP BY c.id
|
|
) x
|
|
WHERE x.id = tt.id AND
|
|
(
|
|
COALESCE(featured_user1_id,-99) <> COALESCE(featured_user1,-99) OR
|
|
COALESCE(featured_user2_id,-99) <> COALESCE(featured_user2,-99) OR
|
|
COALESCE(featured_user3_id,-99) <> COALESCE(featured_user3,-99) OR
|
|
COALESCE(featured_user4_id,-99) <> COALESCE(featured_user4,-99)
|
|
)
|
|
SQL
|
|
|
|
Topic.exec_sql(sql)
|
|
end
|
|
|
|
private
|
|
|
|
def keys(args)
|
|
# Don't include the OP or the last poster
|
|
to_feature = topic.posts.where('user_id NOT IN (?, ?)', topic.user_id, topic.last_post_user_id)
|
|
|
|
# Exclude a given post if supplied (in the case of deletes)
|
|
to_feature = to_feature.where("id <> ?", args[:except_post_id]) if args[:except_post_id].present?
|
|
|
|
# Assign the featured_user{x} columns
|
|
to_feature.group(:user_id).order('count_all desc').limit(TopicFeaturedUsers.count).count.keys
|
|
end
|
|
|
|
def clear
|
|
TopicFeaturedUsers.count.times do |i|
|
|
topic.send("featured_user#{i+1}_id=", nil)
|
|
end
|
|
end
|
|
|
|
def update(user_keys)
|
|
user_keys.each_with_index do |user_id, i|
|
|
topic.send("featured_user#{i+1}_id=", user_id)
|
|
end
|
|
end
|
|
|
|
def update_participant_count
|
|
topic.participant_count = topic.posts.count('distinct user_id')
|
|
end
|
|
end
|