Module: ClosureTree::NumericDeterministicOrdering::ClassMethods

Defined in:
lib/closure_tree/numeric_deterministic_ordering.rb

Instance Method Summary collapse

Instance Method Details

#_ct_sum_order_by(node = nil) ⇒ Object

If node is nil, order the whole tree.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/closure_tree/numeric_deterministic_ordering.rb', line 53

def _ct_sum_order_by(node = nil)
  stats_sql = <<-SQL.squish
    SELECT
      count(*) as total_descendants,
      max(generations) as max_depth
    FROM #{_ct.quoted_hierarchy_table_name}
  SQL
  stats_sql += " WHERE ancestor_id = #{_ct.quote(node.id)}" if node
  h = _ct.connection.select_one(stats_sql)

  depth_column = node ? 'depths.generations' : 'depths.max_depth'

  node_score = "(1 + anc.#{_ct.quoted_order_column(false)}) * " +
    "power(#{h['total_descendants']}, #{h['max_depth'].to_i + 1} - #{depth_column})"

  # We want the NULLs to be first in case we are not ordering roots and they have NULL order.
  Arel.sql("SUM(#{node_score}) IS NULL DESC, SUM(#{node_score})")
end

#roots_and_descendants_preorderedObject



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/closure_tree/numeric_deterministic_ordering.rb', line 72

def roots_and_descendants_preordered
  if _ct.dont_order_roots
    raise ClosureTree::RootOrderingDisabledError.new("Root ordering is disabled on this model")
  end

  join_sql = <<-SQL.squish
    JOIN #{_ct.quoted_hierarchy_table_name} anc_hier
      ON anc_hier.descendant_id = #{_ct.quoted_table_name}.#{_ct.quoted_id_column_name}
    JOIN #{_ct.quoted_table_name} anc
      ON anc.#{_ct.quoted_id_column_name} = anc_hier.ancestor_id
    JOIN (
      SELECT descendant_id, max(generations) AS max_depth
      FROM #{_ct.quoted_hierarchy_table_name}
      GROUP BY descendant_id
    ) #{ _ct.t_alias_keyword } depths ON depths.descendant_id = anc.#{_ct.quoted_id_column_name}
  SQL
  joins(join_sql)
    .group("#{_ct.quoted_table_name}.#{_ct.quoted_id_column_name}")
    .reorder(_ct_sum_order_by)
end