class ActiveFedora::Reflection::AssociationReflection

:nodoc:
Active Record class.
Holds all the meta-data about an association as it was specified in the

def association_class

def association_class
  case macro
  when :contains
    Associations::BasicContainsAssociation
  when :belongs_to
    Associations::BelongsToAssociation
  when :has_and_belongs_to_many
    Associations::HasAndBelongsToManyAssociation
  when :has_many
    Associations::HasManyAssociation
  when :singular_rdf
    Associations::SingularRDF
  when :rdf
    Associations::RDF
  when :directly_contains
    Associations::DirectlyContainsAssociation
  when :directly_contains_one
    Associations::DirectlyContainsOneAssociation
  when :indirectly_contains
    Associations::IndirectlyContainsAssociation
  end
end

def automatic_inverse_of

returns either false or the inverse association name that it finds.
def automatic_inverse_of
  if can_find_inverse_of_automatically?(self)
    inverse_name = ActiveSupport::Inflector.underscore(options[:as] || active_fedora.name.demodulize).to_sym
    begin
      reflection = klass.reflect_on_association(inverse_name)
    rescue NameError
      # Give up: we couldn't compute the klass type so we won't be able
      # to find any associations either.
      reflection = false
    end
    if valid_inverse_reflection?(reflection)
      return inverse_name
    end
  end
  false
end

def can_find_inverse_of_automatically?(reflection)

inverse, so we exclude reflections with scopes.
Anything with a scope can additionally ruin our attempt at finding an

inverse association.
:foreign_key which prevent us from correctly guessing the
Third, we must not have options such as :polymorphic or
have has_many, has_one, belongs_to associations.
inverse_of option cannot be set to false. Second, we must
us from being able to guess the inverse automatically. First, the
Checks to see if the reflection doesn't have any options that prevent
def can_find_inverse_of_automatically?(reflection)
  reflection.options[:inverse_of] != false &&
    VALID_AUTOMATIC_INVERSE_MACROS.include?(reflection.macro) &&
    !INVALID_AUTOMATIC_INVERSE_OPTIONS.any? { |opt| reflection.options[opt] }
    #&& !reflection.scope
end

def chain

ThroughReflection.
A chain of reflections from this one back to the owner. For more see the explanation in
def chain
  [self]
end

def check_validity!

def check_validity!
  check_validity_of_inverse!
end

def check_validity_of_inverse!

def check_validity_of_inverse!
  unless options[:polymorphic]
    if has_inverse? && inverse_of.nil?
      raise InverseOfAssociationNotFoundError.new(self)
    end
  end
end

def create_association(*options)

creation method. Returns the newly created object.
with ActiveFedora::Base#save. +options+ will be passed to the class's
Creates a new instance of the associated class, and immediately saves it
def create_association(*options)
  klass.create(*options)
end

def foreign_key

def foreign_key
  @foreign_key ||= options[:foreign_key] || derive_foreign_key
end

def has_inverse?

def has_inverse?
  inverse_name
end

def initialize(macro, name, options, active_fedora)

def initialize(macro, name, options, active_fedora)
  super
  @collection = [:has_many, :has_and_belongs_to_many, :directly_contains, :indirectly_contains].include?(macro)
end

def inverse_name

def inverse_name
  options.fetch(:inverse_of) do
    if @automatic_inverse_of == false
      nil
    else
      @automatic_inverse_of ||= automatic_inverse_of
    end
  end
end

def inverse_of

def inverse_of
  return unless inverse_name
  @inverse_of ||= klass.reflect_on_association inverse_name
end

def predicate

Returns the RDF predicate as defined by the :predicate option
def predicate
  options[:predicate]
end

def predicate_for_solr

def predicate_for_solr
  predicate.fragment || predicate.to_s.rpartition(/\//).last
end

def solr_key

def solr_key
  @solr_key ||= begin
    ActiveFedora::SolrQueryBuilder.solr_name(predicate_for_solr, :symbol)
  end
end

def valid_inverse_reflection?(reflection)

from calling +klass+, +reflection+ will already be set to false.
Note: klass will always be valid because when there's a NameError

with the current reflection's klass name.
make sure that the reflection's active_record name matches up
+automatic_inverse_of+ method is a valid reflection. We must
Checks if the inverse reflection that is returned from the
def valid_inverse_reflection?(reflection)
  reflection &&
    klass.name == reflection.active_fedora.name &&
    can_find_inverse_of_automatically?(reflection)
end

def validate?

* the association is a +has_many+ association
* you use autosave; :autosave => true
* you explicitly enable validation; :validate => true

:validate => false, validation will take place when:
Unless you explicitly disable validation with

the parent's validation.
Returns whether or not the association should be validated as part of
def validate?
  !options[:validate].nil? ? options[:validate] : (options[:autosave] == true || macro == :has_many)
end