module Formol class Forum < ActiveRecord::Base #Modules include RankedModel include Tracking #Security attr_protected :posts_count, :topics_count #Associations belongs_to :category belongs_to :last_post, :class_name => 'Formol::Post' has_many :topics, :dependent => :destroy has_many :posts, :through => :topics #Validations validates :category, :presence => true validates :label, :presence => true, :length => { :in => 3..32, :allow_blank => true }, :uniqueness => { :scope => :category_id, :case_sensitive => false, :allow_blank => true } validates :description, :length => { :maximum => 128, :allow_blank => true } #Normalization normalize_attribute :label, :with => [:squish, :blank] normalize_attribute :description #Sorting ranks :position, :with_same => :category_id #Scopes class << self # this scope eager loads conveniently topic for using it in breadcrumb def ready_for_breadcrumb includes(:category) end # return all unread forums for a given user def unread(user) unread_scope_base(user) .select('DISTINCT formol_forums.id') .joins(:topics => :last_post) end end #Business class << self # Sorts topics from an array of ids and sets the new category def reorganize(forum_ids, category_id = nil) category = Formol::Category.find(category_id) if category_id #TODO: should maybe optimize this? (forum_ids || []).each_with_index do |forum_id, index| attr = { :position => index } attr[:category] = category if category_id find(forum_id).update_attributes(attr) end end end # Register a post being the last one of the current forum def register_last_post(post) update_attribute(:last_post, post) end # Unregister a post by re-assigning last post. # Needed when a post is destroyed def unregister_last_post update_attributes!(:last_post => posts.order('formol_posts.id').last) end # Mark all unread topics as read for a given user def mark_as_read(user) topics.unread(user).each do |unread| unread.track_for_user!(user) end end def read?(user) topics.unread(user).blank? end end end