2013-08-26 18:41:56 +08:00
|
|
|
class TopicFeaturedUsers
|
|
|
|
attr_reader :topic
|
|
|
|
|
|
|
|
def initialize(topic)
|
|
|
|
@topic = topic
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.count
|
|
|
|
4
|
|
|
|
end
|
|
|
|
|
|
|
|
# Chooses which topic users to feature
|
2017-07-28 09:20:09 +08:00
|
|
|
def choose(args = {})
|
2015-04-06 15:27:05 +08:00
|
|
|
self.class.ensure_consistency!(topic.id.to_i)
|
2013-11-15 03:32:41 +08:00
|
|
|
update_participant_count
|
2013-08-26 18:41:56 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def user_ids
|
2013-11-15 03:32:41 +08:00
|
|
|
[topic.featured_user1_id,
|
|
|
|
topic.featured_user2_id,
|
|
|
|
topic.featured_user3_id,
|
2013-08-26 18:41:56 +08:00
|
|
|
topic.featured_user4_id].uniq.compact
|
|
|
|
end
|
|
|
|
|
2017-07-28 09:20:09 +08:00
|
|
|
def self.ensure_consistency!(topic_id = nil)
|
2014-08-18 15:13:10 +08:00
|
|
|
|
2015-04-22 21:54:54 +08:00
|
|
|
filter = "#{"AND t.id = #{topic_id.to_i}" if topic_id}"
|
2016-06-22 00:59:33 +08:00
|
|
|
filter2 = "#{"AND tt.id = #{topic_id.to_i}" if topic_id}"
|
2015-04-22 21:54:54 +08:00
|
|
|
|
2014-08-18 15:13:10 +08:00
|
|
|
sql = <<SQL
|
|
|
|
|
|
|
|
WITH cte as (
|
|
|
|
SELECT
|
2015-04-06 15:27:05 +08:00
|
|
|
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
|
2014-08-18 15:13:10 +08:00
|
|
|
FROM topics t
|
|
|
|
JOIN posts p ON p.topic_id = t.id
|
2015-04-06 15:27:05 +08:00
|
|
|
WHERE p.deleted_at IS NULL AND
|
|
|
|
NOT p.hidden AND
|
2015-09-25 08:15:58 +08:00
|
|
|
p.post_type in (#{Topic.visible_post_types.join(",")}) AND
|
2015-04-06 15:27:05 +08:00
|
|
|
p.user_id <> t.user_id AND
|
2014-08-18 15:13:10 +08:00
|
|
|
p.user_id <> t.last_post_user_id
|
2015-04-22 21:54:54 +08:00
|
|
|
#{filter}
|
2014-08-18 15:13:10 +08:00
|
|
|
GROUP BY t.id, p.user_id
|
2015-04-06 15:27:05 +08:00
|
|
|
),
|
|
|
|
|
|
|
|
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}
|
2014-08-18 15:13:10 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
UPDATE topics tt
|
|
|
|
SET
|
2016-06-22 00:59:33 +08:00
|
|
|
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 (
|
2014-08-18 15:13:10 +08:00
|
|
|
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
|
2015-04-06 15:27:05 +08:00
|
|
|
FROM cte2 as c
|
2014-08-18 15:13:10 +08:00
|
|
|
GROUP BY c.id
|
2016-06-22 00:59:33 +08:00
|
|
|
) x ON x.id = tt2.id
|
|
|
|
WHERE tt.id = tt2.id AND
|
2014-08-18 15:13:10 +08:00
|
|
|
(
|
2016-06-22 00:59:33 +08:00
|
|
|
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)
|
2015-04-22 21:54:54 +08:00
|
|
|
)
|
2016-06-22 00:59:33 +08:00
|
|
|
#{filter2}
|
2014-08-18 15:13:10 +08:00
|
|
|
SQL
|
|
|
|
|
2018-06-19 14:13:14 +08:00
|
|
|
DB.exec(sql)
|
2014-08-18 15:13:10 +08:00
|
|
|
end
|
|
|
|
|
2013-08-26 18:41:56 +08:00
|
|
|
private
|
|
|
|
|
2018-06-07 13:28:18 +08:00
|
|
|
def update_participant_count
|
|
|
|
count = topic.posts.where('NOT hidden AND post_type in (?)', Topic.visible_post_types).count('distinct user_id')
|
|
|
|
topic.update_columns(participant_count: count)
|
|
|
|
end
|
2013-08-26 18:41:56 +08:00
|
|
|
end
|