class Dhatu::Category < Dhatu::ApplicationRecord # Set Table Name self.table_name = "dhatu_categories" # Including the State Machine Methods include Publishable include Featureable # Callbacks before_validation :generate_permalink, on: :create before_validation :set_top_parent, on: :create after_create :update_permalink, :set_end_node_of_parent after_destroy :set_end_node_of_parent # Validations validate_string :name, mandatory: true, min_length: 2, format: /.*/i validate_string :one_liner, mandatory: false, format: /.*/i validate_string :permalink, mandatory: true, format: /.*/i, min_length: 4, max_length: 128 validates :category_type, :presence=> true, length: {maximum: 64} # Associations belongs_to :parent, :class_name => 'Dhatu::Category', optional: true belongs_to :top_parent, :class_name => 'Dhatu::Category', optional: true has_many :sub_categories, :foreign_key => "parent_id", :class_name => "Dhatu::Category" has_one :category_image, :as => :imageable, :dependent => :destroy, :class_name => "Image::CategoryImage" # --------------- # Class methods # --------------- # return an active record relation object with the search query in its where clause # Return the ActiveRecord::Relation object # == Examples # >>> object.search(query) # => ActiveRecord::Relation object scope :search, lambda {|query| where("LOWER(name) LIKE LOWER('%#{query}%') OR\ LOWER(permalink) LIKE LOWER('%#{query}%') OR\ LOWER(one_liner) LIKE LOWER('%#{query}%') OR\ LOWER(description) LIKE LOWER('%#{query}%')")} scope :filter_by_category_type, lambda { |ctype| where("category_type = ?", ctype) } # Import Methods def self.save_row_data(hsh) # Initializing error hash for displaying all errors altogether error_object = Kuppayam::Importer::ErrorHash.new return error_object if hsh[:name].to_s.strip.blank? category = Dhatu::Category.find_by_name(hsh[:name].to_s.strip) || Dhatu::Category.new category.name = hsh[:name].to_s.strip category.category_type = hsh[:category_type].to_s.strip category.one_liner = hsh[:one_liner].to_s.strip category.description = hsh[:description].to_s.strip parent = Dhatu::Category.find_by_name(hsh[:parent].to_s.strip) category.parent = parent category.top_parent = parent && parent.top_parent ? parent.top_parent : parent category.status = hsh[:status].to_s.strip || PUBLISHED category.priority = hsh[:priority].to_s.strip || 1 # Initializing error hash for displaying all errors altogether error_object = Kuppayam::Importer::ErrorHash.new if category.valid? begin category.save! rescue Exception => e summary = "uncaught #{e} exception while handling connection: #{e.message}" details = "Stack trace: #{e.backtrace.map {|l| " #{l}\n"}.join}" error_object.errors << { summary: summary, details: details } end else summary = "Error while saving category: #{category.name}" details = "Error! #{category.errors.full_messages.to_sentence}" error_object.errors << { summary: summary, details: details } end return error_object end # ------------------ # Instance Methods # ------------------ # Other Methods # ------------------ def display_name self.name end # def to_param # "#{id}-#{name.parameterize[0..32]}" # end def display_category_type self.category_type.try(:demodulize).try(:pluralize).try(:titleize) end def default_image_url(size="medium") "/assets/dhatu/category-#{size}.png" end # Permission Methods # ------------------ def can_be_edited? published? or unpublished? end def can_be_deleted? return false unless removed? return false if end_node == false or self.sub_categories.any? true end def can_be_published? unpublished? or archived? end def can_be_unpublished? return false if end_node == false or self.sub_categories.any? published? or removed? end def can_be_archived? return false if end_node == false or self.sub_categories.any? unpublished? or removed? end def can_be_removed? return false if end_node == false or self.sub_categories.any? published? or unpublished? end # Callback methods # ------------------ def set_end_node! self.update_column(:end_node, self.sub_categories.count < 1) end def set_end_node_of_parent self.parent.set_end_node! if self.parent end protected def generate_permalink return unless self.name if self.parent perm = "#{self.name.parameterize}-#{self.parent.name.parameterize}" else perm = self.name.parameterize end self.permalink = "#{SecureRandom.hex(4)}-#{perm[0..110]}" end def update_permalink if self.parent self.permalink = "#{self.id}-#{self.name.parameterize}-#{self.parent.name.parameterize}" else self.permalink = "#{self.id}-#{self.name.parameterize}" if self.name end self.save end def set_top_parent return if self.parent.blank? if self.parent.top_parent.blank? self.top_parent = self.parent else self.top_parent = self.parent.top_parent end end end