2016-05-04 14:02:47 -04:00
|
|
|
class Tag < ActiveRecord::Base
|
2017-08-25 11:52:18 -04:00
|
|
|
include Searchable
|
|
|
|
|
2016-05-04 14:02:47 -04:00
|
|
|
validates :name, presence: true, uniqueness: true
|
2016-05-30 16:37:06 -04:00
|
|
|
|
|
|
|
has_many :tag_users # notification settings
|
|
|
|
|
2016-05-04 14:02:47 -04:00
|
|
|
has_many :topic_tags, dependent: :destroy
|
|
|
|
has_many :topics, through: :topic_tags
|
2016-05-30 16:37:06 -04:00
|
|
|
|
|
|
|
has_many :category_tags, dependent: :destroy
|
|
|
|
has_many :categories, through: :category_tags
|
2016-05-04 14:02:47 -04:00
|
|
|
|
2016-06-06 14:18:15 -04:00
|
|
|
has_many :tag_group_memberships
|
|
|
|
has_many :tag_groups, through: :tag_group_memberships
|
|
|
|
|
2017-08-25 11:52:18 -04:00
|
|
|
after_save :index_search
|
|
|
|
|
2017-08-22 16:54:28 -04:00
|
|
|
COUNT_ARG = "topics.id"
|
2016-10-28 15:11:43 -04:00
|
|
|
|
|
|
|
# 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)
|
2017-07-27 21:20:09 -04:00
|
|
|
def self.tags_by_count_query(opts = {})
|
2016-10-28 15:11:43 -04:00
|
|
|
q = Tag.joins("LEFT JOIN topic_tags ON tags.id = topic_tags.tag_id")
|
2017-08-22 16:54:28 -04:00
|
|
|
.joins("LEFT JOIN topics ON topics.id = topic_tags.topic_id AND topics.deleted_at IS NULL")
|
2017-07-27 21:20:09 -04:00
|
|
|
.group("tags.id, tags.name")
|
2017-08-22 16:54:28 -04:00
|
|
|
.order('count_topics_id DESC')
|
2016-05-04 14:02:47 -04:00
|
|
|
q = q.limit(opts[:limit]) if opts[:limit]
|
|
|
|
q
|
|
|
|
end
|
|
|
|
|
2017-07-27 21:20:09 -04:00
|
|
|
def self.category_tags_by_count_query(category, opts = {})
|
2016-05-31 16:27:13 -04:00
|
|
|
tags_by_count_query(opts).where("tags.id in (select tag_id from category_tags where category_id = ?)", category.id)
|
2017-07-27 21:20:09 -04:00
|
|
|
.where("topics.category_id = ?", category.id)
|
2016-05-31 16:27:13 -04:00
|
|
|
end
|
|
|
|
|
2016-09-22 15:23:10 -04:00
|
|
|
def self.top_tags(limit_arg: nil, category: nil, guardian: nil)
|
2016-07-07 09:17:56 -04:00
|
|
|
limit = limit_arg || SiteSetting.max_tags_in_filter_list
|
2017-07-27 21:20:09 -04:00
|
|
|
scope_category_ids = (guardian || Guardian.new).allowed_category_ids
|
2016-07-07 09:17:56 -04:00
|
|
|
|
2016-09-22 15:23:10 -04:00
|
|
|
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
|
|
|
|
)
|
2016-07-07 09:17:56 -04:00
|
|
|
|
2017-07-27 21:20:09 -04:00
|
|
|
tags.count(COUNT_ARG).map { |name, _| name }
|
2016-07-07 09:17:56 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.include_tags?
|
|
|
|
SiteSetting.tagging_enabled && SiteSetting.show_filter_by_tag
|
2016-05-04 14:02:47 -04:00
|
|
|
end
|
2016-08-01 22:54:32 -04:00
|
|
|
|
|
|
|
def full_url
|
|
|
|
"#{Discourse.base_url}/tags/#{self.name}"
|
|
|
|
end
|
2017-08-25 11:52:18 -04:00
|
|
|
|
|
|
|
def index_search
|
|
|
|
SearchIndexer.index(self)
|
|
|
|
end
|
2016-05-04 14:02:47 -04:00
|
|
|
end
|
2016-05-29 20:45:32 -04:00
|
|
|
|
|
|
|
# == Schema Information
|
|
|
|
#
|
|
|
|
# Table name: tags
|
|
|
|
#
|
|
|
|
# id :integer not null, primary key
|
|
|
|
# name :string not null
|
|
|
|
# topic_count :integer default(0), not null
|
2017-12-05 10:29:14 -05:00
|
|
|
# created_at :datetime
|
|
|
|
# updated_at :datetime
|
2016-05-29 20:45:32 -04:00
|
|
|
#
|
|
|
|
# Indexes
|
|
|
|
#
|
|
|
|
# index_tags_on_name (name) UNIQUE
|
|
|
|
#
|