module Forestify::InstanceMethods

Public Instance Methods

children() click to toggle source

Returns an ActiveRecord::Relation looking for descendents.

Example :

@audi.children.all # => []
@vehicle.children.all # => [@car, @plane, @boat, @audi]
# File lib/forestify.rb, line 114
def children
  [] if leaf?
  self.class.where('forestify_left_position > ?', self.forestify_left_position).where('forestify_right_position < ?', self.forestify_right_position)
end
initialize_position() click to toggle source

Initialize position fields Should be run only once

# File lib/forestify.rb, line 48
def initialize_position
  # @parent = -1 is the option 'No parent'
  if @parent_id.nil? || @parent_id == "-1"
    # No parent has been specified, we need to add this leaf
    # to the right side of the last root node.
    last = self.class.order("forestify_right_position DESC").first
    self.forestify_left_position = (last.nil?) ? 0 : last.forestify_right_position + 1
    self.forestify_right_position = self.forestify_left_position + 1
    self.forestify_level = 0
  else
    @parent_id = @parent_id.to_i
    p = self.class.find(@parent_id)
    self.forestify_left_position = p.forestify_right_position
    self.forestify_right_position = self.forestify_left_position + 1
    self.forestify_level = p.forestify_level + 1
    # update nodes on the right hand side of parent
    self.class.update_all "forestify_left_position = forestify_left_position + 2", ['forestify_left_position > ?', p.forestify_right_position]
    self.class.update_all "forestify_right_position = forestify_right_position + 2", ['forestify_right_position > ?', p.forestify_right_position]
    # update parent
    p.update_attribute 'forestify_right_position', p.forestify_right_position + 2
  end
end
leaf?() click to toggle source

Returns whether the instance is a leaf or not.

Example :

@car.leaf? # => false
@animal.leaf? # => true
# File lib/forestify.rb, line 151
def leaf?
  !node?
end
node?() click to toggle source

Returns whether the instance is a node or not.

Example :

@car.node? # => true
@animal.node? # => false
# File lib/forestify.rb, line 140
def node?
  (self.forestify_right_position - self.forestify_left_position) > 1
end
parent() click to toggle source

Returns the direct parent, or nil if none exists.

Example :

@vehicle.parent # => nil
@car.parent # => @vehicle
# File lib/forestify.rb, line 103
def parent
  self.parents.where('forestify_level = ?', self.forestify_level - 1).first
end
parents() click to toggle source

Returns an ActiveRecord::Relation looking for ancestors.

Example :

@audi.parents.all # => [@vehicle, @car]
# File lib/forestify.rb, line 92
def parents
  self.class.where('forestify_left_position < ?', self.forestify_left_position).where('forestify_right_position > ?', self.forestify_right_position)
end
siblings() click to toggle source

Returns an ActiveRecord::Relation looking for siblings.

Example :

@vehicle.siblings.all => # [@animal]
# File lib/forestify.rb, line 125
def siblings
  if self.parent.nil?
    self.class.where('forestify_level = 0').where('id != ?', self.id)
  else
    self.parent.children.where('forestify_level = ?', self.forestify_level).where('id != ?', self.id)
  end
end
update_positions_after_delete() click to toggle source
# File lib/forestify.rb, line 71
def update_positions_after_delete
  if node?
    # Update nodes to the right
    self.class.update_all "forestify_left_position = forestify_left_position - 2", ['forestify_left_position > ?', self.forestify_right_position]
    self.class.update_all "forestify_right_position = forestify_right_position - 2", ['forestify_right_position > ?', self.forestify_right_position]
    # Update children
    self.class.update_all "forestify_level = forestify_level - 1", ['forestify_left_position > ? AND forestify_right_position < ?', self.forestify_left_position, self.forestify_right_position]
    self.class.update_all "forestify_left_position = forestify_left_position - 1, forestify_right_position = forestify_right_position - 1", ['forestify_left_position > ? AND forestify_right_position < ?', self.forestify_left_position, self.forestify_right_position]
  else
    # Update nodes to the right
    self.class.update_all "forestify_left_position = forestify_left_position - 2", ['forestify_left_position > ?', self.forestify_right_position]
    self.class.update_all "forestify_right_position = forestify_right_position - 2", ['forestify_right_position > ?', self.forestify_right_position]
  end
end