Skip to content

Commit

Permalink
Add option on how to handle orphans when arranging nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
kbrock committed Oct 24, 2024
1 parent e8e0bb1 commit 78bc14e
Showing 1 changed file with 17 additions and 4 deletions.
21 changes: 17 additions & 4 deletions lib/ancestry/class_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,29 @@ def arrange(options = {})
# arranges array of nodes to a hierarchical hash
#
# @param nodes [Array[Node]] nodes to be arranged
# @param orphan_strategy [Symbol] :rootify or :destroy (default: :rootify)
# @returns Hash{Node => {Node => {}, Node => {}}}
# If a node's parent is not included, the node will be included as if it is a top level node
def arrange_nodes(nodes)
def arrange_nodes(nodes, orphan_strategy: :rootify)
node_ids = Set.new(nodes.map(&:id))
index = Hash.new { |h, k| h[k] = {} }

nodes.each_with_object({}) do |node, arranged|
children = index[node.id]
index[node.parent_id][node] = children
arranged[node] = children unless node_ids.include?(node.parent_id)
index[node.parent_id][node] = children = index[node.id]
if node.parent_id.nil?
arranged[node] = children
elsif !node_ids.include?(node.parent_id)
case orphan_strategy
when :destroy
# All children are destroyed as well (default)
when :adopt
raise ArgumentError, "Not Implemented"
when :rootify
arranged[node] = children
when :restrict
raise Ancestry::AncestryException, I18n.t("ancestry.cannot_delete_descendants")
end
end
end
end

Expand Down

0 comments on commit 78bc14e

Please sign in to comment.