class Tag < ActiveRecord::Base include Searchable validates :name, presence: true, uniqueness: true has_many :tag_users # notification settings has_many :topic_tags, dependent: :destroy has_many :topics, through: :topic_tags has_many :category_tags, dependent: :destroy has_many :categories, through: :category_tags has_many :tag_group_memberships has_many :tag_groups, through: :tag_group_memberships after_save :index_search COUNT_ARG = "topics.id" # Apply more activerecord filters to the tags_by_count_query, and then # fetch the result with .count(Tag::COUNT_ARG). # # e.g., Tag.tags_by_count_query.where("topics.category_id = ?", category.id).count(Tag::COUNT_ARG) def self.tags_by_count_query(opts = {}) q = Tag.joins("LEFT JOIN topic_tags ON tags.id = topic_tags.tag_id") .joins("LEFT JOIN topics ON topics.id = topic_tags.topic_id AND topics.deleted_at IS NULL") .group("tags.id, tags.name") .order('count_topics_id DESC') q = q.limit(opts[:limit]) if opts[:limit] q end def self.category_tags_by_count_query(category, opts = {}) tags_by_count_query(opts).where("tags.id in (select tag_id from category_tags where category_id = ?)", category.id) .where("topics.category_id = ?", category.id) end def self.top_tags(limit_arg: nil, category: nil, guardian: nil) limit = limit_arg || SiteSetting.max_tags_in_filter_list scope_category_ids = (guardian || Guardian.new).allowed_category_ids if category scope_category_ids &= ([category.id] + category.subcategories.pluck(:id)) end tags = DiscourseTagging.filter_allowed_tags( tags_by_count_query(limit: limit).where("topics.category_id in (?)", scope_category_ids), nil, # Don't pass guardian. You might not be able to use some tags, but should still be able to see where they've been used. category: category ) tags.count(COUNT_ARG).map { |name, _| name } end def self.include_tags? SiteSetting.tagging_enabled && SiteSetting.show_filter_by_tag end def full_url "#{Discourse.base_url}/tags/#{self.name}" end def index_search SearchIndexer.index(self) end end # == Schema Information # # Table name: tags # # id :integer not null, primary key # name :string not null # topic_count :integer default(0), not null # created_at :datetime # updated_at :datetime # # Indexes # # index_tags_on_name (name) UNIQUE #