class Shoulda::Matchers::ActiveRecord::AssociationMatchers::ModelReflection

@private

def associated_class

def associated_class
  if polymorphic?
    subject
  else
    reflection.klass
  end
end

def association_foreign_key

def association_foreign_key
  if has_and_belongs_to_many_reflection
    join_model = has_and_belongs_to_many_reflection.options[:class]
    join_model.right_reflection.foreign_key
  else
    reflection.association_foreign_key
  end
end

def association_relation(related_instance)

def association_relation(related_instance)
  relation = associated_class.all
  if reflection.scope
    # Source: AR::Associations::AssociationScope#eval_scope
    relation.instance_exec(related_instance, &reflection.scope)
  else
    relation
  end
end

def foreign_key

def foreign_key
  if has_and_belongs_to_many_reflection
    has_and_belongs_to_many_reflection.foreign_key
  elsif reflection.respond_to?(:foreign_key)
    reflection.foreign_key
  else
    reflection.primary_key_name
  end
end

def has_and_belongs_to_many_name

def has_and_belongs_to_many_name
  reflection.options[:through]
end

def has_and_belongs_to_many_name_table_name

def has_and_belongs_to_many_name_table_name
  has_and_belongs_to_many_reflection&.table_name
end

def has_and_belongs_to_many_reflection

def has_and_belongs_to_many_reflection
  @_has_and_belongs_to_many_reflection ||=
    if has_and_belongs_to_many_name
      @subject.reflect_on_association(has_and_belongs_to_many_name)
    end
end

def initialize(reflection)

def initialize(reflection)
  super(reflection)
  @reflection = reflection
  @subject = reflection.active_record
end

def join_table_name

def join_table_name
  join_table_name =
    has_and_belongs_to_many_name_table_name || reflection.join_table
  join_table_name.to_s
end

def polymorphic?

def polymorphic?
  reflection.options[:polymorphic]
end

def strict_loading?

def strict_loading?
  reflection.options.fetch(:strict_loading, subject.strict_loading_by_default)
end

def through?

def through?
  reflection.options[:through]
end

def validate_inverse_of_through_association!

def validate_inverse_of_through_association!
  if through?
    reflection.check_validity!
  end
end