module ErpTechSvcs::Utils::DefaultNestedSetMethods::ClassMethods
Public Instance Methods
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 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
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
# 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 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
# File lib/erp_tech_svcs/utils/default_nested_set_methods.rb, line 38 def find_roots where("parent_id is null") end
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
# 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