module ClosureTree::NumericDeterministicOrdering::ClassMethods

Public Instance Methods

_ct_sum_order_by(node = nil) click to toggle source

If node is nil, order the whole tree.

# 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_preordered() click to toggle source
# 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