module ErpTechSvcs::Utils::DefaultNestedSetMethods::ClassMethods

Public Instance Methods

build_tree_from_nodes(node_iids) click to toggle source

Build a tree based on internal identifiers passed

@param [Array] Array of internal identifiers @return [Array] Tree from nodes

# File lib/erp_tech_svcs/utils/default_nested_set_methods.rb, line 92
def build_tree_from_nodes(node_iids)
  tree = []

  # first we convert the nodes to a hash based array
  node_iids.each do |node_iid|
    node = self.iid(node_iid)

    tree << node.to_hash({only: [{id: :record_id}, :parent_id, :internal_identifier],
                          leaf: node.leaf?,
                          text: node.to_label,
                          children: []})
  end

  # next we need to build the tree structure based on the nodes
  sorted_tree = tree.dup
  tree.each do |node_hash|
    node = self.find(node_hash[:record_id])

    parent_node = nil
    if node.parent
      parent_node = find_parent_in_tree(sorted_tree, node.parent.id)
    end

    if parent_node
      # add to children of parent
      parent_node[:children] << node_hash

      # remove from updated tree
      sorted_tree.delete_if { |item| node_hash[:record_id] == item[:record_id] }
    end
  end

  sorted_tree
end
delete_from_tree(tree, id) click to toggle source

Delete nodes from a tree based on passed ids

@param [Integer, Array] Either an Id or an array of ids to remove @return [Array] Tree with items removed

# File lib/erp_tech_svcs/utils/default_nested_set_methods.rb, line 131
def delete_from_tree(tree, id)
  if id.is_a? Array
    id.each do |_id|
      delete_from_tree(tree, _id)
    end
  else
    tree.each do |node|
      if node[:record_id] == id
        tree.delete(node)
      end

      if node[:children]
        delete_from_tree(node[:children], id)
      end
    end
  end

  tree
end
find_by_ancestor_iids(iids) click to toggle source

find_by_ancestor_iids allows you to find a nested set element by the internal_identifiers in its ancestry for example, to find a GlAccount whose internal_identifier is “site_4”, and whose parent’s internal_identifier is “nightly_room_charge” and whose grandparent’s internal_identifier is “charge”, you would make this call: gl_account = GlAccount.find_by_iids(['charge', 'nightly_room_charge', “site_4”])

# File lib/erp_tech_svcs/utils/default_nested_set_methods.rb, line 51
def find_by_ancestor_iids(iids)
  node = nil

  if iids.is_a? Array
    iids.each do |iid|
      if (iid == iids.first)
        node = where("parent_id is null and internal_identifier = ?", iid).first
      else
        node = where("parent_id = ? and internal_identifier = ?", node.id, iid).first
      end
    end
  end

  node
end
find_children(parent_id = nil) click to toggle source
# File lib/erp_tech_svcs/utils/default_nested_set_methods.rb, line 42
def find_children(parent_id = nil)
  parent_id.to_i == 0 ? self.roots : find(parent_id).children
end
find_or_create(iid, description, parent=nil) click to toggle source

find existing node or create it and return it. Parent can be passed which will scope this node by the parent

# File lib/erp_tech_svcs/utils/default_nested_set_methods.rb, line 69
def find_or_create(iid, description, parent=nil)
  # look for it
  record = if parent
    parent.children.find_by_internal_identifier(iid)
  else
    find_by_internal_identifier(iid)
  end

  unless record
    record = create(description: description, internal_identifier: iid)

    if parent
      record.move_to_child_of(parent)
    end
  end

  record
end
find_roots() click to toggle source
# File lib/erp_tech_svcs/utils/default_nested_set_methods.rb, line 38
def find_roots
  where("parent_id is null")
end
to_all_representation(parent=nil, container_arr=[], level=0, ancestors=nil) click to toggle source

returns an array of hashes which represent all nodes in nested set order, each of which consists of the node's id, internal identifier and representation if a parent is passed it starts there in the tree

# File lib/erp_tech_svcs/utils/default_nested_set_methods.rb, line 12
def to_all_representation(parent=nil, container_arr=[], level=0, ancestors=nil)
  if parent
    parent.children.each do |node|
      container_arr << {id: node.id,
                        description: node.to_representation(level),
                        internal_identifier: node.internal_identifier}

      unless node.leaf?
        to_all_representation(node, container_arr, (level + 1))
      end

    end
  else
    ancestors = (ancestors || self.roots)
    ancestors.each do |root|
      container_arr << {id: root.id,
                        description: root.to_representation(level),
                        internal_identifier: root.internal_identifier}

      to_all_representation(root, container_arr, (level + 1))
    end
  end

  container_arr
end

Private Instance Methods

find_parent_in_tree(tree, id) click to toggle source
# File lib/erp_tech_svcs/utils/default_nested_set_methods.rb, line 153
def find_parent_in_tree(tree, id)
  parent = nil

  tree.each do |node|
    if node[:record_id] == id
      parent = node
      break
    end

    if node[:children]
      parent = find_parent_in_tree(node[:children], id)

      if parent
        break
      end
    end
  end

  parent
end