class BlogCategory include LuckySneaks::StringExtensions include Mongoid::Document include Mongoid::Timestamps include Mongoid::Tree # Mongoid ======================================================================================== field :name field :description field :slug # Behavior ======================================================================================= before_destroy :destroy_children before_save :set_slug has_and_belongs_to_many :posts validates_presence_of :name validates_uniqueness_of :name # Class methods: Overrides ======================================================================= def self.children super.asc :name end def self.roots super.asc :name end # Class methods ================================================================================== def self.by_name value self.find :first, :conditions => {:name => value} end def self.by_slug value self.find :first, :conditions => {:slug => /^#{value}$/i} end def self.roots_with_posts self.roots.asc(:name).select{ |c| c.has_posts? } end # Instance methods: Overrides ==================================================================== def children_with_posts self.children.asc(:name).select{ |c| c.has_posts? } end def parent_id= value self[:parent_id] = value == 'nil' ? nil : value end # Instance methods =============================================================================== def has_posts? ! self.all_posts.blank? end def parent_category=(name) unless name.blank? self.parent = BlogCategory.find_or_create_by :name => name self.save end end def all_posts (self.posts + self.children.map{ |c| c.posts }).uniq.flatten end def subcategory? ! self.root? end def url "#{Blog.first.path}topics/#{self.slug}" end private # Returns an array of this category's and its ancestors' names. def ancestors_and_self_names self.ancestors_and_self.map{ |l| l.name } end # Returns the permalink for this locale. def set_slug self.slug = (ancestors_and_self_names * '/').to_url.gsub('-slash-', '/') end end