cirandas.net

ref: master

app/models/category.rb


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
class Category < ApplicationRecord

  attr_accessible :name, :parent_id, :display_color, :display_in_menu, :image_builder, :environment, :parent

  SEARCHABLE_FIELDS = {
    :name => {:label => _('Name'), :weight => 10},
    :acronym => {:label => _('Acronym'), :weight => 5},
    :abbreviation => {:label => _('Abbreviation'), :weight => 5},
    :slug => {:label => _('Slug'), :weight => 1},
  }

  validates_exclusion_of :slug, :in => [ 'index' ], :message => N_('{fn} cannot be like that.').fix_i18n
  validates_presence_of :name, :environment_id
  validates_uniqueness_of :slug,:scope => [ :environment_id, :parent_id ], :message => N_('{fn} is already being used by another category.').fix_i18n
  belongs_to :environment

  scope :alphabetical, -> { order 'name ASC' }

  # Finds all top level categories for a given environment.
  scope :top_level_for, -> environment {
    where 'parent_id is null and environment_id = ?', environment.id
  }

  scope :on_level, -> parent { where :parent_id => parent }

  extend ActsAsFilesystem::ActsMethods
  acts_as_filesystem

  has_many :article_categorizations
  has_many :articles, :through => :article_categorizations
  has_many :comments, :through => :articles

  has_many :events, :through => :article_categorizations, :class_name => 'Event', :source => :article

  has_many :profile_categorizations
  has_many :profiles, :through => :profile_categorizations, :source => :profile
  has_many :enterprises, :through => :profile_categorizations, :source => :profile, :class_name => 'Enterprise'
  has_many :people, :through => :profile_categorizations, :source => :profile, :class_name => 'Person'
  has_many :communities, :through => :profile_categorizations, :source => :profile, :class_name => 'Community'

  extend ActsAsHavingImage::ClassMethods
  acts_as_having_image

  before_save :normalize_display_color

  def normalize_display_color
    display_color.gsub!('#', '') if display_color
    display_color = nil if display_color.blank?
  end

  scope :from_types, -> types {
    if types.select{ |t| t.blank? }.empty? then
      where(type: types) else
      where("type IN (?) OR type IS NULL", types.reject{ |t| t.blank? }) end
  }

  after_save :change_children_choosable

  def recent_people(limit = 10)
    self.people.reorder('created_at DESC, id DESC').paginate(page: 1, per_page: limit)
  end

  def recent_enterprises(limit = 10)
    self.enterprises.reorder('created_at DESC, id DESC').paginate(page: 1, per_page: limit)
  end

  def recent_communities(limit = 10)
    self.communities.reorder('created_at DESC, id DESC').paginate(page: 1, per_page: limit)
  end

  def recent_articles(limit = 10)
    self.articles.recent(limit)
  end

  def recent_comments(limit = 10)
    self.comments.reorder('created_at DESC, comments.id DESC').paginate(page: 1, per_page: limit)
  end

  def most_commented_articles(limit = 10)
    self.articles.most_commented(limit)
  end

  def upcoming_events(limit = 10)
    self.events.where('start_date >= ?', DateTime.now.beginning_of_day).order('start_date').paginate(page: 1, per_page: limit)
  end

  def display_in_menu?
    display_in_menu
  end

  def may_change_choosable?
    self.children.present? and (self.parent.blank? or not self.parent.choosable)
  end

  def children_for_menu
    results = []
    pending = children.where(display_in_menu: true).order('path ASC').to_a
    while pending.present?
      cat = pending.shift
      results << cat
      pending += cat.children.where :display_in_menu => true
    end
  end

  def is_leaf_displayable_in_menu?
    return false if self.display_in_menu == false
    self.children.where(:display_in_menu => true).empty?
  end

  def change_children_choosable
    if not self.choosable_was and self.choosable
      self.children.each do |child|
        child.update_attribute :choosable, true
      end
    end
  end

  def with_color
    if display_color.blank?
      parent.nil? ? nil : parent.with_color
    else
      self
    end
  end

end