class Post include LuckySneaks::StringExtensions include Mongoid::Document include Mongoid::Timestamps include Tanker # Constants ====================================================================================== STATES = ['draft', 'published'] # Scopes ========================================================================================= scope :drafts, :where => {:state => 'draft'} scope :published, :where => {:state => 'published'}, :descending => :publication_date scope :by_slug, lambda {|slug| {:where => {:slug.in => ["#{slug}".gsub('//','/'), "/#{slug}/".gsub('//','/')] } } } # Mongoid ======================================================================================== field :title field :title_short # because "title" is often too long for a decent layout field :content field :tags, :type => Array field :slug field :author field :published_at, :type => Date field :state field :publication_date, :type => DateTime field :summary index :slug index :state, :unique => false belongs_to :blog has_and_belongs_to_many :blog_categories # Behavior ======================================================================================= before_save :set_slug validates_uniqueness_of :slug # Tanker ========================================================================================= tankit 'idx' do indexes :author indexes :content indexes :summary indexes :tags indexes :title end after_destroy :delete_tank_indexes after_save :update_tank_indexes # Validations ==================================================================================== validates_presence_of :content, :title # Instance methods: Overrides ==================================================================== def publication_date self[:publication_date] || self.published_at end # Instance methods =============================================================================== def draft? self.state == 'draft' || self.state.nil? end def fix_blog_category_join self.blog_categories.each do |cat| cat.post_ids << self.id cat.save end end def full_path self.path end def humanize_path self.path end def my_index self.blog.posts.index(self) end def next_post i = self.my_index + 1 i = 0 if i > (self.blog.posts.size - 1) self.blog.posts[i] end def path "#{self.blog.path}/#{self.slug}".gsub('//', '/') end def previous_post i = self.my_index - 1 i = self.blog.posts.size - 1 if i < 0 self.blog.posts[i] end def publish! self.update_attributes :state => 'published', :published_at => Time.zone.now end def published? self.state == 'published' end def search_description self.summary.gsub(/<\/?[^>]*>/, '')[0..199].html_safe end def search_title self.title end def unpublish! self.update_attributes :state => 'draft' end def state=(arg) self[:state] = arg.downcase end def status self.state ? self.state.capitalize : 'Draft' end private def set_slug self.slug = self.title.to_s.to_url if self.slug.blank? end end