module FastTree::Model::ClassMethods
¶ ↑
Class Methods
¶ ↑
Public Instance Methods
_create_parent_embedded_space(children)
click to toggle source
# File lib/fast_tree/model.rb, line 60 def _create_parent_embedded_space(children) left = children.max {|c| c.l_ptr}.l_ptr right = children.min {|c| c.r_ptr}.r_ptr sql = <<-"EOS" UPDATE #{self.to_s.underscore.pluralize} SET l_ptr = CASE WHEN l_ptr >= #{left} AND r_ptr <= #{right} THEN l_ptr + 1 WHEN l_ptr > #{right} THEN l_ptr + 2 ELSE l_ptr END, r_ptr = CASE WHEN l_ptr >= #{left} AND r_ptr <= #{right} THEN r_ptr + 1 WHEN l_ptr < #{left} AND r_ptr > #{right} THEN r_ptr + 2 WHEN l_ptr > #{right} THEN r_ptr + 2 ELSE r_ptr END, depth = CASE WHEN l_ptr >= #{left} AND r_ptr <= #{right} THEN depth + 1 ELSE depth END WHERE r_ptr > #{left} EOS ActiveRecord::Base.connection.execute(sql) # return left and right pointers between which parent is embedded {l_ptr: left, r_ptr: right + 2} end
add_parent(parent, children, &block)
click to toggle source
¶ ↑
structure operation
¶ ↑
# File lib/fast_tree/model.rb, line 20 def add_parent(parent, children, &block) parent_depth = children.first.depth # create space for parent ptrs = _create_parent_embedded_space(children) # parent node's pointer parent.l_ptr = ptrs[:l_ptr] parent.r_ptr = ptrs[:r_ptr] parent.depth = parent_depth parent.save end
create_parent(attributes = {}, children, &block)
click to toggle source
# File lib/fast_tree/model.rb, line 33 def create_parent(attributes = {}, children, &block) parent_depth = children.first.depth # create space for parent ptrs = _create_parent_embedded_space(children) # parent node's pointer attributes[:l_ptr] = ptrs[:l_ptr] attributes[:r_ptr] = ptrs[:r_ptr] attributes[:depth] = parent_depth self.create(attributes, &block) end
create_tree(attributes={}, &block)
click to toggle source
# File lib/fast_tree/model.rb, line 47 def create_tree(attributes={}, &block) root = self.find_root if root root else attributes[:l_ptr] = 0 attributes[:r_ptr] = 1 attributes[:depth] = 0 self.create(attributes, &block) end end
find_root()
click to toggle source
find_subtree_by_root(node)
click to toggle source
# File lib/fast_tree/model.rb, line 108 def find_subtree_by_root(node) l_ptr = node.l_ptr r_ptr = node.r_ptr self.where(self.arel_table[:l_ptr].gteq(l_ptr)) .where(self.arel_table[:r_ptr].lteq(r_ptr)) end
print_subtree(root)
click to toggle source
¶ ↑
for debugging
¶ ↑
# File lib/fast_tree/model.rb, line 120 def print_subtree(root) puts("printing sub tree for #{root.name}...") subtree = find_subtree_by_root(root) subtree.order(l_ptr: :asc).each do |st_node| st_node.reload # white spaces on the left wsl = st_node.l_ptr.times.map{|s| "_"}.join('') # arrows ars = (st_node.r_ptr - st_node.l_ptr ).times.map{|s| "-"}.join('') # white spaces on the right wsr = (root.width + 2 - wsl.size - ars.size).times.map{|s| " "}.join('') puts("#{wsl}<#{ars}>#{wsr} ... #{st_node.name}") end puts("done.\n") end