Class: TopicFeaturedUsers

Inherits:
Object
  • Object
show all
Defined in:
app/models/topic_featured_users.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(topic) ⇒ TopicFeaturedUsers

Returns a new instance of TopicFeaturedUsers.



6
7
8
# File 'app/models/topic_featured_users.rb', line 6

def initialize(topic)
  @topic = topic
end

Instance Attribute Details

#topicObject (readonly)

Returns the value of attribute topic.



4
5
6
# File 'app/models/topic_featured_users.rb', line 4

def topic
  @topic
end

Class Method Details

.countObject



10
11
12
# File 'app/models/topic_featured_users.rb', line 10

def self.count
  4
end

.ensure_consistency!(topic_id = nil) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'app/models/topic_featured_users.rb', line 29

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

Instance Method Details

#choose(args = {}) ⇒ Object

Chooses which topic users to feature



15
16
17
18
# File 'app/models/topic_featured_users.rb', line 15

def choose(args = {})
  self.class.ensure_consistency!(topic.id.to_i)
  update_participant_count
end

#user_idsObject



20
21
22
23
24
25
26
27
# File 'app/models/topic_featured_users.rb', line 20

def user_ids
  [
    topic.featured_user1_id,
    topic.featured_user2_id,
    topic.featured_user3_id,
    topic.featured_user4_id,
  ].uniq.compact
end