class ManagedContent include EditorialLogic::Base include Mongoid::Document include Mongoid::Timestamps include Tanker # Constants ====================================================================================== STATES = ['draft', 'published'] # Scopes =================================================================================== scope :drafts, :where => {:state => 'draft'} scope :published, :where => {:state => 'published'} # Mongo Config =================================================================================== field :author field :headline # used as: (1) title element of page; (2) link text of links in FAQ index page - Corey was using this as the header of the page as well. - THIS IS THE QUESTION field :subheader field :slug field :content field :references field :position, :type => Integer field :state, :default => 'draft' field :publication_date, :type => Date field :revision_date, :type => Date field :summary # used as: (1) meta description of page (2) link title attribute of any link pointing to that page field :related_contents, :type => Array, :default => [] field :kind field :breadcrumbs # so FAQ can have breadcrumbs. field :headline_short # because "headline" is often too long for a decent layout. field :keywords # used as: meta keywords index :slug, :unique => true index :state, :unique => false index :kind embedded_in :publication, :inverse_of => :managed_contents embeds_many :sections # Behavior ======================================================================================= alias_method :answer, :content alias_method :definition, :content alias_method :question, :headline alias_method :term, :headline attr_accessor :desired_slug has_slug :desired_slug mount_uploader :document, DocumentUploader, :mount_on => :document_filename store_in :documents # Tanker ========================================================================================= tankit 'idx' do indexes :author indexes :content indexes :headline indexes :keywords indexes :summary end after_destroy :delete_tank_indexes after_save :update_tank_indexes # Validations ==================================================================================== class DesiredSlugPresenceValidator < ActiveModel::EachValidator def validate_each(object, attribute, value) unless object.desired_slug || object.slug object.errors[attribute] << (options[:message] || ' cannot be blank.') end end end class ContentPresenceValidator < ActiveModel::EachValidator def validate_each(object, attribute, value) unless object.kind == 'Multiple Pages' || object.kind == 'Document' if value.blank? object.errors[attribute] << (options[:message] || ' cannot be blank.') end end end end class DocumentPresenceValidator < ActiveModel::EachValidator def validate_each(object, attribute, value) if object.kind == 'Document' if value.blank? object.errors[attribute] << (options[:message] || ' file attachment cannot be blank.') end end end end validates :content, :content_presence => true validates :desired_slug, :desired_slug_presence => true validates_presence_of :headline validates_uniqueness_of :slug # Instance methods =============================================================================== def add_related_content(content_id) self.related_contents ||= [] self.related_contents << content_id unless self.related_contents.include?(content_id) end def clear_related_content self.related_contents = [] end def content=(text) self[:content] = text self.revision_date = Time.zone.now end def has_sections? self.kind == 'Multiple Pages' end def humanize_path self.path end def path kind == 'Document' ? self.document_url : "/#{self.publication.slug}/#{self.slug}".gsub('//', '/') end def publish! self.update_attributes :state => 'published', :publication_date => Time.zone.now end def related_content related = [] if self.related_contents self.related_contents.each do |id| related << self.publication.managed_contents.find(id.to_s) end end related end def related_content=(ids) clear_related_content ids.each{ |id| add_related_content(id) unless id.blank? } self.save end def search_description self.summary.gsub(/<\/?[^>]*>/, '')[0..199].html_safe end def search_title self.headline end def state=(state) self[:state] = state.downcase end end