Class: ThroughHierarchy::Hierarchicals::Instance

Inherits:
Hierarchical
  • Object
show all
Defined in:
lib/through_hierarchy/hierarchicals/instance.rb

Instance Attribute Summary

Attributes inherited from Hierarchical

#source

Instance Method Summary collapse

Methods inherited from Hierarchical

#and_conditions, #foreign_key_column, #foreign_key_name, #foreign_type_column, #foreign_type_name, #hierarchy_joins, #hierarchy_models, #hierarchy_rank, #initialize, #join_best_rank, #model_key, #model_type, #or_conditions, #spawn, #with_instance

Constructor Details

This class inherits a constructor from ThroughHierarchy::Hierarchicals::Hierarchical

Instance Method Details

#best_rankObject



46
47
48
# File 'lib/through_hierarchy/hierarchicals/instance.rb', line 46

def best_rank
  hierarchy_rank.minimum.as(best_rank_column_name)
end

#best_rank_columnObject



42
43
44
# File 'lib/through_hierarchy/hierarchicals/instance.rb', line 42

def best_rank_column
  @source[best_rank_column_name]
end

#best_rank_column_nameObject



38
39
40
# File 'lib/through_hierarchy/hierarchicals/instance.rb', line 38

def best_rank_column_name
  "through_hierarchy_best_rank"
end

#best_rank_subquery(group_by) ⇒ Object

Return a new Hierarchical::Instance representing a subquery that contains only best-rank sources.



70
71
72
73
74
75
76
77
78
79
# File 'lib/through_hierarchy/hierarchicals/instance.rb', line 70

def best_rank_subquery(group_by)
  @source.respond_to?(:project) or raise ThroughHierarchySourceError, "#{@source} cannot be converted into a subquery"
  subq = source.
    project(foreign_type_column, foreign_key_column, group_by, best_rank).
    where(filters).
    group(source[group_by]).
    as(best_rank_table_name)

  spawn(subq)
end

#best_rank_table_nameObject



50
51
52
# File 'lib/through_hierarchy/hierarchicals/instance.rb', line 50

def best_rank_table_name
  "through_hierarchy_best_rank"
end

#create_withObject



23
24
25
26
27
28
# File 'lib/through_hierarchy/hierarchicals/instance.rb', line 23

def create_with
  {
    foreign_type_name => instance_type(@instance),
    foreign_key_name => instance_key(@instance)
  }
end

#filter(instance) ⇒ Object



18
19
20
21
# File 'lib/through_hierarchy/hierarchicals/instance.rb', line 18

def filter(instance)
  foreign_type_column.eq(instance_type(instance)).
    and(foreign_key_column.eq(instance_key(instance)))
end

#filtersObject



14
15
16
# File 'lib/through_hierarchy/hierarchicals/instance.rb', line 14

def filters
  or_conditions(hierarchy_instances.compact.map{|instance| filter(instance)})
end

#hierarchy_instancesObject



10
11
12
# File 'lib/through_hierarchy/hierarchicals/instance.rb', line 10

def hierarchy_instances
  [@instance] + @hierarchy.map{|m| @instance.association(m).load_target}
end

#instance_key(instance) ⇒ Object



34
35
36
# File 'lib/through_hierarchy/hierarchicals/instance.rb', line 34

def instance_key(instance)
  instance.attributes[@model.primary_key]
end

#instance_type(instance) ⇒ Object



30
31
32
# File 'lib/through_hierarchy/hierarchicals/instance.rb', line 30

def instance_type(instance)
  instance.class.base_class.to_s
end

#select_best_rank(group_by:) ⇒ Object

Select only sources with best hierarchy rank for target instance Uses subquery grouped by specified column to compute best rank TODO: experiment with the model-style double-join method instead



57
58
59
60
61
62
63
64
65
66
# File 'lib/through_hierarchy/hierarchicals/instance.rb', line 57

def select_best_rank(group_by:)
  sub = best_rank_subquery(group_by)
  @source.
    join(sub.source).
    on(
      hierarchy_rank.eq(sub.best_rank_column).
        and(@source[group_by].eq(sub.source[group_by]))
    ).
    order(@source[group_by])
end

#set_target(target) ⇒ Object



4
5
6
7
8
# File 'lib/through_hierarchy/hierarchicals/instance.rb', line 4

def set_target(target)
  @target = target
  @instance = @target
  @model = @target.class        
end