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 raise NotImplementedError 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 return inverse_name if valid_inverse_reflection?(reflection) end false end
def belongs_to?
def belongs_to? false end
def calculate_constructable(_macro, _options)
def calculate_constructable(_macro, _options) true 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 check_validity!
def check_validity! check_validity_of_inverse! end
def check_validity_of_inverse!
def check_validity_of_inverse! return if options[:polymorphic] || !(has_inverse? && inverse_of.nil?) raise InverseOfAssociationNotFoundError, self end
def collect_join_chain
A chain of reflections from this one back to the owner. For more see the explanation in
def collect_join_chain [self] end
def collection?
association. Returns +true+ if the +macro+ is either +has_many+ or
Returns whether or not this association reflection is for a collection
def collection? false end
def constructable? # :nodoc:
def constructable? # :nodoc: @constructable 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 derive_foreign_key
def derive_foreign_key if belongs_to? "#{name}_id" elsif has_and_belongs_to_many? "#{name.to_s.singularize}_ids" elsif options[:as] "#{options[:as]}_id" elsif inverse_of&.collection? # for a has_many that is the inverse of a has_and_belongs_to_many "#{options[:inverse_of].to_s.singularize}_ids" else # for a has_many that is the inverse of a belongs_to active_fedora.name.foreign_key end end
def foreign_key
def foreign_key @foreign_key ||= options[:foreign_key] || derive_foreign_key end
def has_and_belongs_to_many?
def has_and_belongs_to_many? false end
def has_inverse?
def has_inverse? inverse_name end
def has_many?
def has_many? false end
def initialize(name, scope, options, active_fedora)
def initialize(name, scope, options, active_fedora) super @constructable = calculate_constructable(macro, options) 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 macro
Returns the macro type.
def macro raise NotImplementedError 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 ||= ActiveFedora.index_field_mapper.solr_name(predicate_for_solr, :symbol) 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