class Category < ActiveRecord::Base ##--- Associaciones has_and_belongs_to_many :products belongs_to :parent, :class_name => "Category" has_many :children, -> { where "status!= 0" }, :class_name => "Category", :foreign_key => 'parent_id' enum status: [ :erased, :active, :inactive ] ##--- Llevar registro de Actividad del usuario audited ##--- Validaciones previas de guardar validates :category , presence: { message: "Debe capturar el nombre de la lĂ­nea de producto." } ##--- Tipo de vistas / consultas scope :vigentes, -> { where( "status != 0").order(" status ASC, category ASC") } scope :activos, -> { where( "status = 1").order(" category ASC") } scope :activos_padre, -> { where( "status = 1 AND parent_id = 0").order(" category ASC") } scope :get_parents, -> { where( "parent_id = 0 and status != 0").order(" category ASC") } def descendents self_and_descendents - [self] end def self_and_descendents self.class.tree_for(self) end def self.tree_for(instance) where("#{table_name}.id IN (#{tree_sql_for(instance)})").order("#{table_name}.id") end def self.tree_sql_for(instance) tree_sql = <<-SQL WITH RECURSIVE search_tree(id, path) AS ( SELECT id, ARRAY[id] FROM #{table_name} WHERE id = #{instance.id} UNION ALL SELECT #{table_name}.id, path || #{table_name}.id FROM search_tree JOIN #{table_name} ON #{table_name}.parent_id = search_tree.id WHERE NOT #{table_name}.id = ANY(path) ) SELECT id FROM search_tree ORDER BY path SQL end protected before_save do self.parent_id = 0 if parent_id.nil? end end