discourse/app/models/category.rb

87 lines
2.7 KiB
Ruby

class Category < ActiveRecord::Base
belongs_to :topic
belongs_to :user
has_many :topics
has_many :category_featured_topics
has_many :featured_topics, through: :category_featured_topics, source: :topic
has_many :category_featured_users
has_many :featured_users, through: :category_featured_users, source: :user
validates_presence_of :name
validates_uniqueness_of :name
validate :uncategorized_validator
after_save :invalidate_site_cache
after_destroy :invalidate_site_cache
def uncategorized_validator
return errors.add(:name, I18n.t(:is_reserved)) if name == SiteSetting.uncategorized_name
return errors.add(:slug, I18n.t(:is_reserved)) if slug == SiteSetting.uncategorized_name
end
def self.popular
order('topic_count desc')
end
def self.update_stats
exec_sql "UPDATE categories
SET topics_week = (SELECT COUNT(*)
FROM topics as ft
WHERE ft.category_id = categories.id
AND ft.created_at > (CURRENT_TIMESTAMP - INTERVAL '1 WEEK')
AND ft.visible),
topics_month = (SELECT COUNT(*)
FROM topics as ft
WHERE ft.category_id = categories.id
AND ft.created_at > (CURRENT_TIMESTAMP - INTERVAL '1 MONTH')
AND ft.visible),
topics_year = (SELECT COUNT(*)
FROM topics as ft
WHERE ft.category_id = categories.id
AND ft.created_at > (CURRENT_TIMESTAMP - INTERVAL '1 YEAR')
AND ft.visible)"
end
# Use the first paragraph of the topic's first post as the excerpt
def excerpt
if topic.present?
first_post = topic.posts.order(:post_number).first
body = first_post.cooked
matches = body.scan(/\<p\>(.*)\<\/p\>/)
if matches and matches[0] and matches[0][0]
return matches[0][0]
end
end
nil
end
def topic_url
topic.try(:relative_url)
end
before_save do
self.slug = Slug.for(self.name)
end
after_create do
topic = Topic.create!(title: I18n.t("category.topic_prefix", category: name), user: user, visible: false)
topic.posts.create!(raw: SiteSetting.category_post_template, user: user)
update_column(:topic_id, topic.id)
topic.update_column(:category_id, self.id)
end
# We cache the categories in the site json, so we need to invalidate it when they change
def invalidate_site_cache
Site.invalidate_cache
end
before_destroy do
topic.destroy
end
end