Module: ClosureTree::HashTreeSupport

Included in:
Support
Defined in:
lib/closure_tree/hash_tree_support.rb

Instance Method Summary collapse

Instance Method Details

#build_hash_tree(tree_scope) ⇒ Object

Builds nested hash structure using the scope returned from the passed in scope



50
51
52
53
54
55
56
57
58
59
# File 'lib/closure_tree/hash_tree_support.rb', line 50

def build_hash_tree(tree_scope)
  tree = ActiveSupport::OrderedHash.new
  id_to_hash = {}

  tree_scope.each do |ea|
    h = id_to_hash[ea.id] = ActiveSupport::OrderedHash.new
    (id_to_hash[ea._ct_parent_id] || tree)[ea] = h
  end
  tree
end

#default_tree_scope(scope, limit_depth = nil) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/closure_tree/hash_tree_support.rb', line 5

def default_tree_scope(scope, limit_depth = nil)
  # Deepest generation, within limit, for each descendant
  # NOTE: Postgres requires HAVING clauses to always contains aggregate functions (!!)

  # Get the hierarchy table for the scope's model class
  hierarchy_table_arel = if scope.respond_to?(:hierarchy_class)
                           scope.hierarchy_class.arel_table
                         elsif scope.klass.respond_to?(:hierarchy_class)
                           scope.klass.hierarchy_class.arel_table
                         else
                           hierarchy_table
                         end

  model_table_arel = scope.klass.arel_table

  # Build the subquery using Arel
  subquery = hierarchy_table_arel
             .project(
               hierarchy_table_arel[:descendant_id],
               hierarchy_table_arel[:generations].maximum.as('depth')
             )
             .group(hierarchy_table_arel[:descendant_id])

  # Add HAVING clause if limit_depth is specified
  subquery = subquery.having(hierarchy_table_arel[:generations].maximum.lteq(limit_depth - 1)) if limit_depth

  generation_depth_alias = subquery.as('generation_depth')

  # Build the join
  join_condition = model_table_arel[scope.klass.primary_key].eq(generation_depth_alias[:descendant_id])

  join_source = model_table_arel
                .join(generation_depth_alias)
                .on(join_condition)
                .join_sources

  scope_with_order(scope.joins(join_source), 'generation_depth.depth')
end

#hash_tree(tree_scope, limit_depth = nil) ⇒ Object



44
45
46
47
# File 'lib/closure_tree/hash_tree_support.rb', line 44

def hash_tree(tree_scope, limit_depth = nil)
  limited_scope = limit_depth ? tree_scope.where("#{quoted_hierarchy_table_name}.generations <= #{limit_depth - 1}") : tree_scope
  build_hash_tree(limited_scope)
end