Class: ActiveRecord::Associations::JoinDependency

Inherits:
Object
  • Object
show all
Defined in:
lib/active_record/associations/join_dependency.rb,
lib/active_record/associations/join_dependency/join_base.rb,
lib/active_record/associations/join_dependency/join_part.rb,
lib/active_record/associations/join_dependency/join_association.rb

Overview

:nodoc:

Defined Under Namespace

Classes: JoinAssociation, JoinBase, JoinPart

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base, associations, joins) ⇒ JoinDependency

Returns a new instance of JoinDependency.



10
11
12
13
14
15
16
17
18
19
# File 'lib/active_record/associations/join_dependency.rb', line 10

def initialize(base, associations, joins)
  @active_record = base
  @table_joins   = joins
  @join_parts    = [JoinBase.new(base)]
  @associations  = {}
  @reflections   = []
  @alias_tracker = AliasTracker.new(base.connection, joins)
  @alias_tracker.aliased_name_for(base.table_name) # Updates the count for base.table_name to 1
  build(associations)
end

Instance Attribute Details

#active_recordObject (readonly)

Returns the value of attribute active_record.



8
9
10
# File 'lib/active_record/associations/join_dependency.rb', line 8

def active_record
  @active_record
end

#alias_trackerObject (readonly)

Returns the value of attribute alias_tracker.



8
9
10
# File 'lib/active_record/associations/join_dependency.rb', line 8

def alias_tracker
  @alias_tracker
end

#join_partsObject (readonly)

Returns the value of attribute join_parts.



8
9
10
# File 'lib/active_record/associations/join_dependency.rb', line 8

def join_parts
  @join_parts
end

#reflectionsObject (readonly)

Returns the value of attribute reflections.



8
9
10
# File 'lib/active_record/associations/join_dependency.rb', line 8

def reflections
  @reflections
end

Instance Method Details

#columnsObject



37
38
39
40
41
42
43
44
# File 'lib/active_record/associations/join_dependency.rb', line 37

def columns
  join_parts.collect { |join_part|
    table = join_part.aliased_table
    join_part.column_names_with_alias.collect{ |column_name, aliased_name|
      table[column_name].as Arel.sql(aliased_name)
    }
  }.flatten
end

#graft(*associations) ⇒ Object



21
22
23
24
25
26
27
# File 'lib/active_record/associations/join_dependency.rb', line 21

def graft(*associations)
  associations.each do |association|
    join_associations.detect {|a| association == a} ||
      build(association.reflection.name, association.find_parent_in(self) || join_base, association.join_type)
  end
  self
end

#instantiate(rows) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/active_record/associations/join_dependency.rb', line 46

def instantiate(rows)
  primary_key = join_base.aliased_primary_key
  parents = {}

  records = rows.map { |model|
    primary_id = model[primary_key]
    parent = parents[primary_id] ||= join_base.instantiate(model)
    construct(parent, @associations, join_associations, model)
    parent
  }.uniq

  remove_duplicate_results!(active_record, records, @associations)
  records
end

#join_associationsObject



29
30
31
# File 'lib/active_record/associations/join_dependency.rb', line 29

def join_associations
  join_parts.last(join_parts.length - 1)
end

#join_baseObject



33
34
35
# File 'lib/active_record/associations/join_dependency.rb', line 33

def join_base
  join_parts.first
end

#remove_duplicate_results!(base, records, associations) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/active_record/associations/join_dependency.rb', line 61

def remove_duplicate_results!(base, records, associations)
  case associations
  when Symbol, String
    reflection = base.reflections[associations]
    remove_uniq_by_reflection(reflection, records)
  when Array
    associations.each do |association|
      remove_duplicate_results!(base, records, association)
    end
  when Hash
    associations.keys.each do |name|
      reflection = base.reflections[name]
      remove_uniq_by_reflection(reflection, records)

      parent_records = []
      records.each do |record|
        if descendant = record.send(reflection.name)
          if reflection.collection?
            parent_records.concat descendant.target.uniq
          else
            parent_records << descendant
          end
        end
      end

      remove_duplicate_results!(reflection.klass, parent_records, associations[name]) unless parent_records.empty?
    end
  end
end