123456789_123456789_123456789_123456789_123456789_

Class: ActiveRecord::Associations::JoinDependency::JoinAssociation

Do not use. This class is for internal use only.
Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, JoinPart
Instance Chain:
Inherits: ActiveRecord::Associations::JoinDependency::JoinPart
Defined in: activerecord/lib/active_record/associations/join_dependency/join_association.rb

Class Method Summary

Instance Attribute Summary

JoinPart - Inherited

#attribute_types,
#base_klass

The Active Record class which this join part is associated ‘about’; for a JoinBase this is the actual base model, for a JoinAssociation this is the target model of the association.

#children

The Active Record class which this join part is associated ‘about’; for a JoinBase this is the actual base model, for a JoinAssociation this is the target model of the association.

#column_names, #primary_key, #table_name

::Enumerable - Included

#many?

Returns true if the enumerable has more than 1 element.

Instance Method Summary

JoinPart - Inherited

::Enumerable - Included

#compact_blank

Returns a new ::Array without the blank items.

#exclude?

The negative of the Enumerable#include?.

#excluding

Returns a copy of the enumerable excluding the specified elements.

#in_order_of

Returns a new ::Array where the order has been set to that provided in the series, based on the key of the objects in the original enumerable.

#including

Returns a new array that includes the passed elements.

#index_by

Convert an enumerable to a hash, using the block result as the key and the element as the value.

#index_with

Convert an enumerable to a hash, using the element as the key and the block result as the value.

#maximum

Calculates the maximum from the extracted elements.

#minimum

Calculates the minimum from the extracted elements.

#pick

Extract the given key from the first element in the enumerable.

#pluck

Extract the given key from each element in the enumerable.

#sole

Returns the sole item in the enumerable.

#without
#as_json

::ActiveSupport::EnumerableCoreExt::Constants - Included

Constructor Details

.new(reflection, children) ⇒ JoinAssociation

[ GitHub ]

  
# File 'activerecord/lib/active_record/associations/join_dependency/join_association.rb', line 13

def initialize(reflection, children)
  super(reflection.klass, children)

  @reflection = reflection
end

Instance Attribute Details

#readonly?Boolean (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/associations/join_dependency/join_association.rb', line 81

def readonly?
  return @readonly if defined?(@readonly)

  @readonly = reflection.scope && reflection.scope_for(base_klass.unscoped).readonly_value
end

#reflection (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/associations/join_dependency/join_association.rb', line 10

attr_reader :reflection, :tables

#strict_loading?Boolean (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/associations/join_dependency/join_association.rb', line 87

def strict_loading?
  return @strict_loading if defined?(@strict_loading)

  @strict_loading = reflection.scope && reflection.scope_for(base_klass.unscoped).strict_loading_value
end

#table (rw)

[ GitHub ]

  
# File 'activerecord/lib/active_record/associations/join_dependency/join_association.rb', line 11

attr_accessor :table

#tables (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/associations/join_dependency/join_association.rb', line 10

attr_reader :reflection, :tables

Instance Method Details

#append_constraints(connection, join, constraints) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/associations/join_dependency/join_association.rb', line 94

def append_constraints(connection, join, constraints)
  if join.is_a?(Arel::Nodes::StringJoin)
    join_string = Arel::Nodes::And.new(constraints.unshift join.left)
    join.left = Arel.sql(connection.visitor.compile(join_string))
  else
    right = join.right
    right.expr = Arel::Nodes::And.new(constraints.unshift right.expr)
  end
end

#join_constraints(foreign_table, foreign_klass, join_type, alias_tracker)

[ GitHub ]

  
# File 'activerecord/lib/active_record/associations/join_dependency/join_association.rb', line 24

def join_constraints(foreign_table, foreign_klass, join_type, alias_tracker)
  joins = []
  chain = []

  reflection_chain = reflection.chain
  reflection_chain.each_with_index do |reflection, index|
    table, terminated = yield reflection, reflection_chain[index..]
    @table ||= table

    if terminated
      foreign_table, foreign_klass = table, reflection.klass
      break
    end

    chain << [reflection, table]
  end

  base_klass.with_connection do |connection|
    # The chain starts with the target table, but we want to end with it here (makes
    # more sense in this context), so we reverse
    chain.reverse_each do |reflection, table|
      klass = reflection.klass

      scope = reflection.join_scope(table, foreign_table, foreign_klass)

      unless scope.references_values.empty?
        associations = scope.eager_load_values | scope.includes_values

        unless associations.empty?
          scope.joins! scope.construct_join_dependency(associations, Arel::Nodes::OuterJoin)
        end
      end

      arel = scope.arel(alias_tracker.aliases)
      nodes = arel.constraints.first

      if nodes.is_a?(Arel::Nodes::And)
        others = nodes.children.extract! do |node|
          !Arel.fetch_attribute(node) { |attr| attr.relation.name == table.name }
        end
      end

      joins << join_type.new(table, Arel::Nodes::On.new(nodes))

      if others && !others.empty?
        joins.concat arel.join_sources
        append_constraints(connection, joins.last, others)
      end

      # The current table in this iteration becomes the foreign table in the next
      foreign_table, foreign_klass = table, klass
    end
  end

  joins
end

#match?(other) ⇒ Boolean

[ GitHub ]

  
# File 'activerecord/lib/active_record/associations/join_dependency/join_association.rb', line 19

def match?(other)
  return true if self == other
  super && reflection == other.reflection
end