Class: CategoryFeaturedTopic
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- CategoryFeaturedTopic
- Defined in:
- app/models/category_featured_topic.rb
Constant Summary collapse
- NEXT_CATEGORY_ID_KEY =
"category-featured-topic:next-category-id"
- DEFAULT_BATCH_SIZE =
100
Class Method Summary collapse
- .clear_batch! ⇒ Object
-
.feature_topics(batched: false, batch_size: nil) ⇒ Object
Populates the category featured topics.
- .feature_topics_for(c, existing = nil) ⇒ Object
Class Method Details
.clear_batch! ⇒ Object
42 43 44 |
# File 'app/models/category_featured_topic.rb', line 42 def self.clear_batch! Discourse.redis.del(NEXT_CATEGORY_ID_KEY) end |
.feature_topics(batched: false, batch_size: nil) ⇒ Object
Populates the category featured topics.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'app/models/category_featured_topic.rb', line 11 def self.feature_topics(batched: false, batch_size: nil) current = {} CategoryFeaturedTopic .select(:topic_id, :category_id) .order(:rank) .each { |f| (current[f.category_id] ||= []) << f.topic_id } batch_size ||= DEFAULT_BATCH_SIZE next_category_id = batched ? Discourse.redis.get(NEXT_CATEGORY_ID_KEY).to_i : 0 categories = Category .select(:id, :topic_id, :num_featured_topics) .where("id >= ?", next_category_id) .order("id ASC") .limit(batch_size) .to_a if batched if categories.length == batch_size next_id = Category.where("id > ?", categories.last.id).order(:id).pick(:id) next_id ? Discourse.redis.setex(NEXT_CATEGORY_ID_KEY, 1.day, next_id) : clear_batch! else clear_batch! end end categories.each { |c| CategoryFeaturedTopic.feature_topics_for(c, current[c.id] || []) } end |
.feature_topics_for(c, existing = nil) ⇒ Object
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 |
# File 'app/models/category_featured_topic.rb', line 46 def self.feature_topics_for(c, existing = nil) return if c.blank? query_opts = { per_page: c.num_featured_topics, except_topic_ids: [c.topic_id], visible: true, no_definitions: true, } # It may seem a bit odd that we are running 2 queries here, when admin # can clearly pull out all the topics needed. # We do so, so anonymous will ALWAYS get some topics # If we only fetched as admin we may have a situation where anon can see # no featured topics (all the previous 2x topics are only visible to admins) # Add topics, even if they're in secured categories or invisible query = TopicQuery.new(Discourse.system_user, query_opts) results = query.list_category_topic_ids(c) # Add some topics that are visible to everyone: anon_query = TopicQuery.new(nil, query_opts.merge(except_topic_ids: [c.topic_id] + results)) results += anon_query.list_category_topic_ids(c) results.uniq! return if results == existing CategoryFeaturedTopic.transaction do CategoryFeaturedTopic.where(category_id: c.id).delete_all results.each_with_index do |topic_id, idx| c.category_featured_topics.create(topic_id: topic_id, rank: idx) end end end |