Module: AdvancedRelationshipManagement::RecursiveRelationships

Extended by:
ActiveSupport::Concern
Defined in:
lib/advanced_relationship_management/recursive_relationships.rb

Instance Method Summary collapse

Instance Method Details

#ancestorsObject



50
51
52
53
54
55
56
# File 'lib/advanced_relationship_management/recursive_relationships.rb', line 50

def ancestors
  if AdvancedRelationshipManagement.enable_caching
    Rails.cache.fetch([self, "ancestors"]) { fetch_ancestors }
  else
    fetch_ancestors
  end
end

#depth(node) ⇒ Object



86
87
88
# File 'lib/advanced_relationship_management/recursive_relationships.rb', line 86

def depth(node)
  node.ancestors.size
end

#depth_of_ancestorsObject



78
79
80
81
82
83
84
# File 'lib/advanced_relationship_management/recursive_relationships.rb', line 78

def depth_of_ancestors
  ancestors_with_depth = {}
  ancestors.each do |ancestor|
    ancestors_with_depth[ancestor] = depth(ancestor)
  end
  ancestors_with_depth
end

#depth_of_descendantsObject



70
71
72
73
74
75
76
# File 'lib/advanced_relationship_management/recursive_relationships.rb', line 70

def depth_of_descendants
  descendants_with_depth = {}
  descendants.each do |descendant|
    descendants_with_depth[descendant] = depth(descendant)
  end
  descendants_with_depth
end

#descendants(*scopes) ⇒ Object



19
20
21
22
23
24
25
# File 'lib/advanced_relationship_management/recursive_relationships.rb', line 19

def descendants(*scopes)
  if AdvancedRelationshipManagement.enable_caching
    Rails.cache.fetch([self, "descendants"] + scopes) { fetch_descendants(*scopes) }
  else
    fetch_descendants(*scopes)
  end
end

#fetch_ancestorsObject



58
59
60
61
62
63
64
65
66
67
68
# File 'lib/advanced_relationship_management/recursive_relationships.rb', line 58

def fetch_ancestors
  all_ancestors = []
  ActiveRecord::Base.silence do
    current_node = self
    while current_node.parent
      all_ancestors << current_node.parent
      current_node = current_node.parent
    end
  end
  all_ancestors
end

#fetch_descendants(*scopes) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/advanced_relationship_management/recursive_relationships.rb', line 27

def fetch_descendants(*scopes)
  relation = self.class.find_by_sql([<<-SQL, id])
    WITH RECURSIVE descendants_cte AS (
      SELECT *
      FROM #{self.class.table_name}
      WHERE #{self.class.child_column_name} = ?
      UNION ALL
      SELECT #{self.class.table_name}.*
      FROM #{self.class.table_name}
      INNER JOIN descendants_cte ON descendants_cte.#{self.class.child_column_name} = #{self.class.table_name}.#{self.class.parent_column_name}
    )
    SELECT *
    FROM descendants_cte
  SQL
  
  scopes.each do |scope|
    relation = relation.public_send(scope) if scope.is_a?(Symbol)
    relation = relation.merge(scope) if scope.is_a?(ActiveRecord::Relation)
  end
  
  relation
end

#setup_recursive_relationshipsObject



12
13
14
15
16
17
# File 'lib/advanced_relationship_management/recursive_relationships.rb', line 12

def setup_recursive_relationships
  return if self.class.reflect_on_association(:children) && self.class.reflect_on_association(:parent)
  
  parent_column = self.class.parent_column_name
  self.class.setup_relationships(parent_column)
end