2013-02-05 14:16:51 -05:00
|
|
|
class Category < ActiveRecord::Base
|
|
|
|
|
|
|
|
belongs_to :topic
|
|
|
|
belongs_to :user
|
|
|
|
|
|
|
|
has_many :topics
|
2013-02-07 10:45:24 -05:00
|
|
|
has_many :category_featured_topics
|
2013-02-05 14:16:51 -05:00
|
|
|
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
|
|
|
|
|
2013-02-19 22:24:38 -05:00
|
|
|
validates_presence_of :user_id
|
2013-02-05 14:16:51 -05:00
|
|
|
validates_presence_of :name
|
2013-02-07 10:45:24 -05:00
|
|
|
validates_uniqueness_of :name
|
2013-02-05 14:16:51 -05:00
|
|
|
validate :uncategorized_validator
|
|
|
|
|
|
|
|
after_save :invalidate_site_cache
|
|
|
|
after_destroy :invalidate_site_cache
|
|
|
|
|
2013-02-07 10:45:24 -05:00
|
|
|
def uncategorized_validator
|
2013-02-05 14:16:51 -05:00
|
|
|
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
|
2013-02-16 15:57:16 -05:00
|
|
|
|
|
|
|
# Recalculates `topics_year`, `topics_month`, and `topics_week`
|
|
|
|
# for each Category.
|
2013-02-05 14:16:51 -05:00
|
|
|
def self.update_stats
|
2013-02-16 15:57:16 -05:00
|
|
|
topics = Topic
|
|
|
|
.select("COUNT(*)")
|
|
|
|
.where("topics.category_id = categories.id")
|
|
|
|
.visible
|
|
|
|
|
|
|
|
topics_year = topics.created_since(1.year.ago).to_sql
|
|
|
|
topics_month = topics.created_since(1.month.ago).to_sql
|
|
|
|
topics_week = topics.created_since(1.week.ago).to_sql
|
|
|
|
|
|
|
|
Category.update_all("topics_year = (#{topics_year}),
|
|
|
|
topics_month = (#{topics_month}),
|
|
|
|
topics_week = (#{topics_week})")
|
2013-02-05 14:16:51 -05:00
|
|
|
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
|
2013-02-07 10:45:24 -05:00
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
nil
|
|
|
|
end
|
|
|
|
|
|
|
|
def topic_url
|
|
|
|
topic.try(:relative_url)
|
|
|
|
end
|
2013-02-07 10:45:24 -05:00
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
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)
|
2013-02-07 10:45:24 -05:00
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
|
|
|
|
# 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
|