Module: ClosureTree::NumericDeterministicOrdering

Extended by:
ActiveSupport::Concern
Defined in:
lib/closure_tree/numeric_deterministic_ordering.rb

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#add_sibling(sibling_node, add_after = true) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/closure_tree/numeric_deterministic_ordering.rb', line 63

def add_sibling(sibling_node, add_after = true)
  fail "can't add self as sibling" if self == sibling_node
  _ct.with_advisory_lock do
    if self.order_value.nil? || siblings_before.without(sibling_node).empty?
      update_attribute(:order_value, 0)
    end
    sibling_node.parent = self.parent
    starting_order_value = self.order_value.to_i
    to_reorder = siblings_after.without(sibling_node).to_a
    if add_after
      to_reorder.unshift(sibling_node)
    else
      to_reorder.unshift(self)
      sibling_node.update_attribute(:order_value, starting_order_value)
    end

    to_reorder.each_with_index do |ea, idx|
      ea.update_attribute(:order_value, starting_order_value + idx + 1)
    end
    sibling_node.reload # because the parent may have changed.
  end
end

#append_sibling(sibling_node) ⇒ Object



55
56
57
# File 'lib/closure_tree/numeric_deterministic_ordering.rb', line 55

def append_sibling(sibling_node)
  add_sibling(sibling_node, true)
end

#prepend_sibling(sibling_node) ⇒ Object



59
60
61
# File 'lib/closure_tree/numeric_deterministic_ordering.rb', line 59

def prepend_sibling(sibling_node)
  add_sibling(sibling_node, false)
end

#self_and_descendants_preorderedObject



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/closure_tree/numeric_deterministic_ordering.rb', line 6

def self_and_descendants_preordered
  # TODO: raise NotImplementedError if sort_order is not numeric and not null?
  h = _ct.connection.select_one(<<-SQL)
    SELECT
      count(*) as total_descendants,
      max(generations) as max_depth
    FROM #{_ct.quoted_hierarchy_table_name}
    WHERE ancestor_id = #{_ct.quote(self.id)}
  SQL
  join_sql = <<-SQL
    JOIN #{_ct.quoted_hierarchy_table_name} anc_hier
      ON anc_hier.descendant_id = #{_ct.quoted_hierarchy_table_name}.descendant_id
    JOIN #{_ct.quoted_table_name} anc
      ON anc.id = anc_hier.ancestor_id
    JOIN #{_ct.quoted_hierarchy_table_name} depths
      ON depths.ancestor_id = #{_ct.quote(self.id)} AND depths.descendant_id = anc.id
  SQL
  node_score = "(1 + anc.#{_ct.quoted_order_column(false)}) * " +
    "power(#{h['total_descendants']}, #{h['max_depth'].to_i + 1} - depths.generations)"
  order_by = "sum(#{node_score})"
  self_and_descendants.joins(join_sql).group("#{_ct.quoted_table_name}.id").reorder(order_by)
end