Module: Forestify::InstanceMethods

Defined in:
lib/forestify.rb

Instance Method Summary collapse

Instance Method Details

#childrenObject

Returns an ActiveRecord::Relation looking for descendents.

Example :

@audi.children.all # => []
@vehicle.children.all # => [@car, @plane, @boat, @audi]


114
115
116
117
# 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_positionObject

Initialize position fields Should be run only once



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# 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?Boolean

Returns whether the instance is a leaf or not.

Example :

@car.leaf? # => false
@animal.leaf? # => true

Returns:

  • (Boolean)


151
152
153
# File 'lib/forestify.rb', line 151

def leaf?
  !node?
end

#node?Boolean

Returns whether the instance is a node or not.

Example :

@car.node? # => true
@animal.node? # => false

Returns:

  • (Boolean)


140
141
142
# File 'lib/forestify.rb', line 140

def node?
  (self.forestify_right_position - self.forestify_left_position) > 1
end

#parentObject

Returns the direct parent, or nil if none exists.

Example :

@vehicle.parent # => nil
@car.parent # => @vehicle


103
104
105
# File 'lib/forestify.rb', line 103

def parent
  self.parents.where('forestify_level = ?', self.forestify_level - 1).first
end

#parentsObject

Returns an ActiveRecord::Relation looking for ancestors.

Example :

@audi.parents.all # => [@vehicle, @car]


92
93
94
# 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

#siblingsObject

Returns an ActiveRecord::Relation looking for siblings.

Example :

@vehicle.siblings.all => # [@animal]


125
126
127
128
129
130
131
# 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_deleteObject



71
72
73
74
75
76
77
78
79
80
81
82
83
84
# 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