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 = < 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