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
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)
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
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)
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
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)
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?
* 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