Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add option on how to handle orphans when arranging nodes #661

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions lib/ancestry/class_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,27 @@ 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 then raise ArgumentError, "Not Implemented"
when :rootify
arranged[node] = children
when :restrict
raise Ancestry::AncestryException.new(I18n.t("ancestry.cannot_delete_descendants"))
end
end
end
end

Expand Down