Class: ActiveRecord::Associations::ClassMethods::JoinDependency

Inherits:
Object
  • Object
show all
Defined in:
lib/active_record/associations.rb

Overview

:nodoc:

Direct Known Subclasses

InnerJoinDependency

Defined Under Namespace

Classes: JoinAssociation, JoinBase

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base, associations, joins) ⇒ JoinDependency

Returns a new instance of JoinDependency.



1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
# File 'lib/active_record/associations.rb', line 1813

def initialize(base, associations, joins)
  @joins                 = [JoinBase.new(base, joins)]
  @associations          = associations
  @reflections           = []
  @base_records_hash     = {}
  @base_records_in_order = []
  @table_aliases         = Hash.new { |aliases, table| aliases[table] = 0 }
  @table_aliases[base.table_name] = 1
  build(associations)
end

Instance Attribute Details

#joinsObject (readonly)

Returns the value of attribute joins.



1811
1812
1813
# File 'lib/active_record/associations.rb', line 1811

def joins
  @joins
end

#reflectionsObject (readonly)

Returns the value of attribute reflections.



1811
1812
1813
# File 'lib/active_record/associations.rb', line 1811

def reflections
  @reflections
end

#table_aliasesObject (readonly)

Returns the value of attribute table_aliases.



1811
1812
1813
# File 'lib/active_record/associations.rb', line 1811

def table_aliases
  @table_aliases
end

Instance Method Details

#instantiate(rows) ⇒ Object



1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
# File 'lib/active_record/associations.rb', line 1832

def instantiate(rows)
  rows.each_with_index do |row, i|
    primary_id = join_base.record_id(row)
    unless @base_records_hash[primary_id]
      @base_records_in_order << (@base_records_hash[primary_id] = join_base.instantiate(row))
    end
    construct(@base_records_hash[primary_id], @associations, join_associations.dup, row)
  end
  remove_duplicate_results!(join_base.active_record, @base_records_in_order, @associations)
  return @base_records_in_order
end

#join_associationsObject



1824
1825
1826
# File 'lib/active_record/associations.rb', line 1824

def join_associations
  @joins[1..-1].to_a
end

#join_baseObject



1828
1829
1830
# File 'lib/active_record/associations.rb', line 1828

def join_base
  @joins[0]
end

#join_for_table_name(table_name) ⇒ Object



1872
1873
1874
1875
1876
# File 'lib/active_record/associations.rb', line 1872

def join_for_table_name(table_name)
  join = (@joins.select{|j|j.aliased_table_name == table_name.gsub(/^\"(.*)\"$/){$1} }.first) rescue nil
  return join unless join.nil?
  @joins.select{|j|j.is_a?(JoinAssociation) && j.aliased_join_table_name == table_name.gsub(/^\"(.*)\"$/){$1} }.first rescue nil
end

#joins_for_table_name(table_name) ⇒ Object



1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
# File 'lib/active_record/associations.rb', line 1878

def joins_for_table_name(table_name)
  join = join_for_table_name(table_name)
  result = nil
  if join && join.is_a?(JoinAssociation)
    result = [join]
    if join.parent && join.parent.is_a?(JoinAssociation)
      result = joins_for_table_name(join.parent.aliased_table_name) +
               result
    end
  end
  result
end

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



1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
# File 'lib/active_record/associations.rb', line 1844

def remove_duplicate_results!(base, records, associations)
  case associations
    when Symbol, String
      reflection = base.reflections[associations]
      if reflection && [:has_many, :has_and_belongs_to_many].include?(reflection.macro)
        records.each { |record| record.send(reflection.name).target.uniq! }
      end
    when Array
      associations.each do |association|
        remove_duplicate_results!(base, records, association)
      end
    when Hash
      associations.keys.each do |name|
        reflection = base.reflections[name]
        is_collection = [:has_many, :has_and_belongs_to_many].include?(reflection.macro)

        parent_records = records.map do |record|
          descendant = record.send(reflection.name)
          next unless descendant
          descendant.target.uniq! if is_collection
          descendant
        end.flatten.compact

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