lib/mongoid_tree.rb in mongoid_tree-0.3.3 vs lib/mongoid_tree.rb in mongoid_tree-0.3.4
- old
+ new
@@ -56,35 +56,55 @@
:inverse_of => :children
# This stores the position in the children array of the parent object.
# Makes it easier to flatten / export / import a tree
field :position, :type => Integer
- field :depth, :type => Integer
end
module InstanceMethods
-
+
+
def parent
- self.parents.last
+ parents.last
end
def depth
- self.parents.count
+ parent_ids.count
end
+
+ def leaf?
+ child_ids.empty?
+ end
+ def root?
+ parent_ids.empty?
+ end
+
+ def root
+ base_class.find(parent_ids.first)
+ end
+
+ def ancestors
+ base_class.where(:id.in => parent_ids)
+ end
+
+ def ancestors_and_self
+ ancestors + [self]
+ end
+
#Comparable
def <=> (another_node)
- self.position <=> another_node.position
+ position <=> another_node.position
end
# Returns the whole subtree including itself as array
def depth_first
result = [self]
- if self.child_ids.empty?
+ if child_ids.empty?
return result
else
- self.children.sort.each do |child|
+ children.sort.each do |child|
result += child.depth_first
end
end
return result
end
@@ -104,49 +124,57 @@
return result
end
alias :bfs :breadth_first
def insert_before( new_child )
- new_child.position = self.position
- self.parent.children.each do |child|
+ new_child.position = position
+ parent.children.each do |child|
if child.position >= new_child.position
child.update_attributes(:position => child.position + 1)
end
end
- self.parent.reload.children << new_child
+ parent.children << new_child
end
def insert_after ( new_child )
- new_child.position = self.position + 1
- self.parent.children.each do |child|
+ new_child.position = position + 1
+ parent.children.each do |child|
if child.position >= new_child.position
child.update_attributes(:position => child.position + 1)
end
end
- self.parent.children << new_child
+ parent.children << new_child
end
def move_to(target_node)
# unhinge - I was getting a nil on another implementation, so this is a bit longer but works
- child_ids_array = self.parent.child_ids.clone
- child_ids_array.delete(self.id)
+ child_ids_array = parent.child_ids.clone
+ child_ids_array.delete(id)
parent.update_attributes(:child_ids => child_ids_array )
self.update_attributes(:parent_ids => [])
# and append
target_node.children << self
# recurse through subtree
- self.rebuild_paths
+ rebuild_paths
end
+
def rebuild_paths
- self.update_path
- self.children.each do |child|
+ update_path
+ children.each do |child|
child.rebuild_paths
end
end
def update_path
self.update_attributes(:parent_ids => self.parent.parent_ids + [self.parent.id])
+ end
+
+ def base_class
+ @base_class ||= begin
+ parent_classes = self.class.ancestors
+ parent_classes[parent_classes.index(Mongoid::Acts::Tree::InstanceMethods) - 1]
+ end
end
end
end
end