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

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

Overview

:nodoc:

Defined Under Namespace

Classes: JoinAssociation, JoinBase

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (JoinDependency) initialize(base, associations, joins)



1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
# File 'activerecord/lib/active_record/associations.rb', line 1841

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

- (Object) joins (readonly)

Returns the value of attribute joins



1839
1840
1841
# File 'activerecord/lib/active_record/associations.rb', line 1839

def joins
  @joins
end

- (Object) reflections (readonly)

Returns the value of attribute reflections



1839
1840
1841
# File 'activerecord/lib/active_record/associations.rb', line 1839

def reflections
  @reflections
end

- (Object) table_aliases (readonly)

Returns the value of attribute table_aliases



1839
1840
1841
# File 'activerecord/lib/active_record/associations.rb', line 1839

def table_aliases
  @table_aliases
end

Instance Method Details

- (Object) count_aliases_from_table_joins(name)



1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
# File 'activerecord/lib/active_record/associations.rb', line 1868

def count_aliases_from_table_joins(name)
  # quoted_name should be downcased as some database adapters (Oracle) return quoted name in uppercase
  quoted_name = join_base.active_record.connection.quote_table_name(name.downcase).downcase
  join_sql = join_base.table_joins.to_s.downcase
  join_sql.blank? ? 0 :
    # Table names
    join_sql.scan(/join(?:\s+\w+)?\s+#{quoted_name}\son/).size +
    # Table aliases
    join_sql.scan(/join(?:\s+\w+)?\s+\S+\s+#{quoted_name}\son/).size
end

- (Object) graft(*associations)



1852
1853
1854
1855
1856
1857
1858
# File 'activerecord/lib/active_record/associations.rb', line 1852

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_class)
  end
  self
end

- (Object) instantiate(rows)



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

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

- (Object) join_associations



1860
1861
1862
# File 'activerecord/lib/active_record/associations.rb', line 1860

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

- (Object) join_base



1864
1865
1866
# File 'activerecord/lib/active_record/associations.rb', line 1864

def join_base
  @joins[0]
end

- (Object) remove_duplicate_results!(base, records, associations)



1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
# File 'activerecord/lib/active_record/associations.rb', line 1891

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