class ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation

:nodoc:

def ==(other)

def ==(other)
  other.class == self.class &&
  other.reflection == reflection &&
  other.parent == parent
end

def aliased_table_name_for(name, suffix = nil)

def aliased_table_name_for(name, suffix = nil)
  if @join_dependency.table_aliases[name].zero?
    @join_dependency.table_aliases[name] = @join_dependency.count_aliases_from_table_joins(name)
  end
  if !@join_dependency.table_aliases[name].zero? # We need an alias
    name = active_record.connection.table_alias_for "#{pluralize(reflection.name)}_#{parent_table_name}#{suffix}"
    @join_dependency.table_aliases[name] += 1
    if @join_dependency.table_aliases[name] == 1 # First time we've seen this name
      # Also need to count the aliases from the table_aliases to avoid incorrect count
      @join_dependency.table_aliases[name] += @join_dependency.count_aliases_from_table_joins(name)
    end
    table_index = @join_dependency.table_aliases[name]
    name = name[0..active_record.connection.table_alias_length-3] + "_#{table_index}" if table_index > 1
  else
    @join_dependency.table_aliases[name] += 1
  end
  name
end

def association_join

def association_join
  return @join if @join
  aliased_table = Arel::Table.new(table_name, :as      => @aliased_table_name,
                                              :engine  => arel_engine,
                                              :columns => klass.columns)
  parent_table = Arel::Table.new(parent.table_name, :as      => parent.aliased_table_name,
                                                    :engine  => arel_engine,
                                                    :columns => parent.active_record.columns)
  as_conditions = reflection.options[:conditions] && process_conditions(reflection.options[:conditions], aliased_table_name)
  @join = case reflection.macro
  when :has_and_belongs_to_many
    join_table = Arel::Table.new(options[:join_table], :as => aliased_join_table_name, :engine => arel_engine)
    fk = options[:foreign_key] || reflection.active_record.to_s.foreign_key
    klass_fk = options[:association_foreign_key] || klass.to_s.foreign_key
    [
      join_table[fk].eq(parent_table[reflection.active_record.primary_key]),
      [aliased_table[klass.primary_key].eq(join_table[klass_fk]), as_conditions].reject{ |x| x.blank? }
    ]
  when :has_many, :has_one
    if reflection.options[:through]
      join_table = Arel::Table.new(through_reflection.klass.table_name, :as => aliased_join_table_name, :engine => arel_engine)
      jt_as_conditions = through_reflection.options[:conditions] && process_conditions(through_reflection.options[:conditions], aliased_table_name)
      jt_as_extra = jt_source_extra = jt_sti_extra = nil
      first_key = second_key = as_extra = nil
      if through_reflection.macro == :belongs_to
        jt_primary_key = through_reflection.primary_key_name
        jt_foreign_key = through_reflection.association_primary_key
      else
        jt_primary_key = through_reflection.active_record_primary_key
        jt_foreign_key = through_reflection.primary_key_name
        if through_reflection.options[:as] # has_many :through against a polymorphic join
          jt_as_extra = join_table[through_reflection.options[:as].to_s + '_type'].eq(parent.active_record.base_class.name)
        end
      end
      case source_reflection.macro
      when :has_many, :has_one
        if source_reflection.options[:as]
          first_key   = "#{source_reflection.options[:as]}_id"
          second_key  = options[:foreign_key] || primary_key
          as_extra    = aliased_table["#{source_reflection.options[:as]}_type"].eq(source_reflection.active_record.base_class.name)
        else
          first_key   = through_reflection.klass.base_class.to_s.foreign_key
          second_key  = options[:foreign_key] || primary_key
        end
        unless through_reflection.klass.descends_from_active_record?
          jt_sti_extra = join_table[through_reflection.active_record.inheritance_column].eq(through_reflection.klass.sti_name)
        end
      when :belongs_to
        first_key = primary_key
        if reflection.options[:source_type]
          second_key = source_reflection.association_foreign_key
          jt_source_extra = join_table[reflection.source_reflection.options[:foreign_type]].eq(reflection.options[:source_type])
        else
          second_key = source_reflection.primary_key_name
        end
      end
      [
        [parent_table[jt_primary_key].eq(join_table[jt_foreign_key]), jt_as_extra, jt_source_extra, jt_sti_extra, jt_as_conditions].reject{|x| x.blank? },
        [aliased_table[first_key].eq(join_table[second_key]), as_extra, as_conditions].reject{ |x| x.blank? }
      ]
    elsif reflection.options[:as]
      id_rel = aliased_table["#{reflection.options[:as]}_id"].eq(parent_table[parent.primary_key])
      type_rel = aliased_table["#{reflection.options[:as]}_type"].eq(parent.active_record.base_class.name)
      [id_rel, type_rel, as_conditions].reject{ |x| x.blank?}
    else
      foreign_key = options[:foreign_key] || reflection.active_record.name.foreign_key
      [aliased_table[foreign_key].eq(parent_table[reflection.options[:primary_key] || parent.primary_key]), as_conditions].reject{ |x| x.blank? }
    end
  when :belongs_to
    [aliased_table[options[:primary_key] || reflection.klass.primary_key].eq(parent_table[options[:foreign_key] || reflection.primary_key_name]), as_conditions].reject{ |x| x.blank? }
  end
  unless klass.descends_from_active_record?
    sti_column = aliased_table[klass.inheritance_column]
    sti_condition = sti_column.eq(klass.sti_name)
    klass.descendants.each {|subclass| sti_condition = sti_condition.or(sti_column.eq(subclass.sti_name)) }
    @join << sti_condition
  end
  @join
end

def find_parent_in(other_join_dependency)

def find_parent_in(other_join_dependency)
  other_join_dependency.joins.detect do |join|
    self.parent == join
  end
end

def initialize(reflection, join_dependency, parent = nil)

def initialize(reflection, join_dependency, parent = nil)
  reflection.check_validity!
  if reflection.options[:polymorphic]
    raise EagerLoadPolymorphicError.new(reflection)
  end
  super(reflection.klass)
  @join_dependency    = join_dependency
  @parent             = parent
  @reflection         = reflection
  @aliased_prefix     = "t#{ join_dependency.joins.size }"
  @parent_table_name  = parent.active_record.table_name
  @aliased_table_name = aliased_table_name_for(table_name)
  @join               = nil
  @join_type          = Arel::InnerJoin
  if reflection.macro == :has_and_belongs_to_many
    @aliased_join_table_name = aliased_table_name_for(reflection.options[:join_table], "_join")
  end
  if [:has_many, :has_one].include?(reflection.macro) && reflection.options[:through]
    @aliased_join_table_name = aliased_table_name_for(reflection.through_reflection.klass.table_name, "_join")
  end
end

def join_relation(joining_relation)

def join_relation(joining_relation)
  self.join_type = Arel::OuterJoin
  joining_relation.joins(self)
end

def pluralize(table_name)

def pluralize(table_name)
  ActiveRecord::Base.pluralize_table_names ? table_name.to_s.pluralize : table_name
end

def process_conditions(conditions, table_name)

def process_conditions(conditions, table_name)
  sanitized = sanitize_sql(conditions, table_name)
  if sanitized =~ /\#\{.*\}/
    ActiveSupport::Deprecation.warn(
      'String-based interpolation of association conditions is deprecated. Please use a ' \
      'proc instead. So, for example, has_many :older_friends, :conditions => \'age > #{age}\' ' \
      'should be changed to has_many :older_friends, :conditions => proc { "age > #{age}" }.'
    )
    instance_eval("%@#{sanitized.gsub('@', '\@')}@", __FILE__, __LINE__)
  elsif conditions.respond_to?(:to_proc)
    conditions = sanitize_sql(instance_eval(&conditions), table_name)
  else
    sanitized
  end
end

def relation

def relation
  aliased = Arel::Table.new(table_name, :as => @aliased_table_name,
                                        :engine => arel_engine,
                                        :columns => klass.columns)
  if reflection.macro == :has_and_belongs_to_many
    [Arel::Table.new(options[:join_table], :as => aliased_join_table_name, :engine => arel_engine), aliased]
  elsif reflection.options[:through]
    [Arel::Table.new(through_reflection.klass.table_name, :as => aliased_join_table_name, :engine => arel_engine), aliased]
  else
    aliased
  end
end

def table_alias_for(table_name, table_alias)

def table_alias_for(table_name, table_alias)
   "#{table_name} #{table_alias if table_name != table_alias}".strip
end

def table_name_and_alias

def table_name_and_alias
  table_alias_for table_name, @aliased_table_name
end