Added block to sort_by_ancestry method for sorting within rank. #85

Closed
wants to merge 2 commits into
from
Jump to file or symbol
Failed to load files and symbols.
+34 −5
Split
@@ -57,14 +57,28 @@ def arrange_nodes(nodes)
end
# Pseudo-preordered array of nodes. Children will always follow parents,
- # but the ordering of nodes within a rank depends on their order in the
- # array that gets passed in
- def sort_by_ancestry(nodes)
- arranged = nodes.is_a?(Hash) ? nodes : arrange_nodes(nodes.sort_by{|n| n.ancestry || '0'})
+ # for ordering nodes within a rank provide block, eg. Node.sort_by_ancestry(Node.all) {|a, b| a.rank <=> b.rank}.
+ def sort_by_ancestry(nodes, &block)
+ arranged = nodes if nodes.is_a?(Hash)
+
+ unless arranged
+ presorted_nodes = nodes.sort do |a, b|
+ a_cestry, b_cestry = a.ancestry || '0', b.ancestry || '0'
+
+ if block_given? && a_cestry == b_cestry
+ yield a, b
+ else
+ a_cestry <=> b_cestry
+ end
+ end
+
+ arranged = arrange_nodes(presorted_nodes)
+ end
+
arranged.inject([]) do |sorted_nodes, pair|
node, children = pair
sorted_nodes << node
- sorted_nodes += sort_by_ancestry(children) unless children.blank?
+ sorted_nodes += sort_by_ancestry(children, &block) unless children.blank?
sorted_nodes
end
end
View
@@ -704,4 +704,19 @@ def test_sort_by_ancestry
assert_equal [n1, n2, n4, n3, n5].map(&:id), arranged.map(&:id)
end
end
+
+ def test_sort_by_ancestry_with_block
+ AncestryTestDatabase.with_model :extra_columns => {:rank => :integer} do |model|
+ n1 = model.create!(:rank => 0)
+ n2 = model.create!(:rank => 1)
+ n3 = model.create!(:rank => 0, :parent => n1)
+ n4 = model.create!(:rank => 0, :parent => n2)
+ n5 = model.create!(:rank => 1, :parent => n1)
+ n6 = model.create!(:rank => 1, :parent => n2)
+
+ arranged = model.sort_by_ancestry(model.all.sort_by(&:rank).reverse) {|a, b| a.rank <=> b.rank}
+ assert_equal [n1, n3, n5, n2, n4, n6].map(&:id), arranged.map(&:id)
+ end
+ end
+
end