module Mongoid::Association::Relatable
This module provides behaviors shared between Association types.
@since 7.0
Constants
- PRIMARY_KEY_DEFAULT
The primary key default.
@return [ String ] The primary key field default.
@since 7.0
- SHARED_OPTIONS
The options shared between all association types.
@return [ Array<Symbol> ] The shared options.
@since 7.0
Attributes
The name of the association.
@return [ Symbol ] The name of the relation.
@since 7.0
The options on this association.
@return [ Hash ] The options.
@since 7.0
Public Class Methods
Initialize the Association.
@param [ Class ] _class The class of the model who owns this relation. @param [ Symbol ] name The name of the association. @param [ Hash ] opts The relation options. @param [ Block ] block The optional block.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 55 def initialize(_class, name, opts = {}, &block) @owner_class = _class @name = name @options = opts @extension = nil create_extension!(&block) validate! end
Public Instance Methods
Compare this association to another.
@return [ Object ] The object to compare to this association.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 69 def ==(other) relation_class_name == other.relation_class_name && inverse_class_name == other.inverse_class_name && name == other.name && options == other.options end
Whether trying to bind an object using this association should raise an error.
@param [ Document ] doc The document to be bound.
@return [ true, false ] Whether the document can be bound.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 106 def bindable?(doc); false; end
Get the counter cache column name.
@return [ String ] The counter cache column name.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 283 def counter_cache_column_name @counter_cache_column_name ||= (@options[:counter_cache].is_a?(String) || @options[:counter_cache].is_a?(Symbol)) ? @options[:counter_cache] : "#{inverse || inverse_class_name.demodulize.underscore.pluralize}_count" end
Create a relation proxy object using the owner and target.
@param [ Document ] owner The document this relation hangs off of. @param [ Document, Array<Document> ] target The target (parent) of the
relation.
@return [ Proxy ]
@since 7.0
# File lib/mongoid/association/relatable.rb, line 265 def create_relation(owner, target) relation.new(owner, target, self) end
Whether the dependent method is destructive.
@return [ true, false ] If the dependent method is destructive.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 274 def destructive? @destructive ||= !!(dependent && (dependent == :delete_all || dependent == :destroy)) end
Get the extension.
@return [ Module ] The extension module, if one has been defined.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 294 def extension @extension ||= @options[:extend] end
Get the name of the method to check if the foreign key has changed.
@example Get the foreign key check method.
association.foreign_key_check
@return [ String ] The foreign key check.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 252 def foreign_key_check @foreign_key_check ||= "#{foreign_key}_changed?" if (stores_foreign_key? && foreign_key) end
The name of the foreign key setter method.
@return [ String ] The name of the foreign key setter.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 216 def foreign_key_setter # note: You can't check if this association stores foreign key # See HasOne and HasMany binding, they referenced foreign_key_setter @foreign_key_setter ||= "#{foreign_key}=" if foreign_key end
Get the callbacks for a given type.
@param [ Symbol ] callback_type The type of callback type.
@return [ Array<Proc, Symbol> ] A list of the callbacks, either method
names or Procs.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 84 def get_callbacks(callback_type) Array(options[callback_type]) end
Get the inverse name.
@return [ Symbol ] The inverse name.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 303 def inverse(other = nil) candidates = inverses(other) candidates.detect { |c| c } if candidates end
Get the inverse's association metadata.
@param [ Object ] other The other model class or model object to use when
determining inverses.
@return [ Association ] The inverse's association metadata.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 133 def inverse_association(other = nil) (other || relation_class).relations[inverse(other)] end
The class of the object owning this relation.
@return [ String ] The owning objects' class.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 178 def inverse_class @owner_class end
The class name of the object owning this relation.
@return [ String ] The owning objects' class name.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 169 def inverse_class_name @inverse_class_name ||= @owner_class.name end
The name of the inverse setter method.
@return [ String ] The name of the inverse setter.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 207 def inverse_setter(other = nil) @inverse_setter ||= "#{inverses(other).first}=" unless inverses(other).blank? end
Get the inverse type.
@return [ nil ] Default is nil for an association.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 142 def inverse_type; end
Gets the setter for the field that sets the type of document on a polymorphic relation.
@example Get the inverse type setter.
association.inverse_type_setter
@return [ String ] The name of the setter.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 240 def inverse_type_setter @inverse_type_setter ||= inverse_type.__setter__ end
Get the inverse names.
@param [ Object ] other The other model class or model object to use when
determining inverses.
@return [ Array<Symbol> ] The list of inverse names.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 116 def inverses(other = nil) return [ inverse_of ] if inverse_of if polymorphic? polymorphic_inverses(other) else determine_inverses(other) end end
The foreign key field if this relation stores a foreign key. Otherwise, the primary key.
@return [ Symbol, String ] The primary key.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 189 def key stores_foreign_key? ? foreign_key : primary_key end
The class of the relation object(s).
@return [ String ] The relation objects' class.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 159 def klass @klass ||= relation_class_name.constantize end
The atomic path for this relation.
@return [ Mongoid::Atomic::Paths::Root ] The atomic path object.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 227 def path(document) relation.path(document) end
The class name of the relation object(s).
@return [ String ] The relation objects' class name.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 149 def relation_class_name @class_name ||= @options[:class_name] || ActiveSupport::Inflector.classify(name) end
The name of the setter on this object for assigning an associated object.
@return [ String ] The setter name.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 198 def setter @setter ||= "#{name}=" end
Get the type setter. @note Only relevant for polymorphic relations that take the :as option.
@return [ String ] The type setter method.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 94 def type_setter @type_setter ||= type.__setter__ end
Whether the associated object(s) should be validated.
@return [ true, false ] If the associated object(s)
should be validated.
@since 7.0
# File lib/mongoid/association/relatable.rb, line 314 def validate? @validate ||= if @options[:validate].nil? validation_default else !!@options[:validate] end end
Private Instance Methods
# File lib/mongoid/association/relatable.rb, line 400 def create_extension!(&block) if block extension_module_name = "#{@owner_class.to_s.demodulize}#{name.to_s.camelize}RelationExtension" silence_warnings do @owner_class.const_set(extension_module_name, Module.new(&block)) end @extension = "#{@owner_class}::#{extension_module_name}".constantize end end
# File lib/mongoid/association/relatable.rb, line 410 def default_inverse @default_inverse ||= klass.relations[inverse_klass.name.underscore] end
# File lib/mongoid/association/relatable.rb, line 334 def define_autosaver! if autosave? Association::Referenced::AutoSave.define_autosave!(self) end end
# File lib/mongoid/association/relatable.rb, line 340 def define_builder! Association::Builders.define_builder!(self) end
# File lib/mongoid/association/relatable.rb, line 368 def define_counter_cache_callbacks! if counter_cached? Association::Referenced::CounterCache.define_callbacks!(self) end end
# File lib/mongoid/association/relatable.rb, line 344 def define_creator! Association::Builders.define_creator!(self) end
# File lib/mongoid/association/relatable.rb, line 374 def define_dependency! if dependent Association::Depending.define_dependency!(self) end end
# File lib/mongoid/association/relatable.rb, line 356 def define_existence_check! Association::Accessors.define_existence_check!(self) end
# File lib/mongoid/association/relatable.rb, line 348 def define_getter! Association::Accessors.define_getter!(self) end
# File lib/mongoid/association/relatable.rb, line 360 def define_ids_getter! Association::Accessors.define_ids_getter!(self) end
# File lib/mongoid/association/relatable.rb, line 364 def define_ids_setter! Association::Accessors.define_ids_setter!(self) end
# File lib/mongoid/association/relatable.rb, line 352 def define_setter! Association::Accessors.define_setter!(self) end
# File lib/mongoid/association/relatable.rb, line 328 def define_touchable! if touchable? Association::Touchable.define_touchable!(self) end end
# File lib/mongoid/association/relatable.rb, line 394 def polymorph! if polymorphic? @owner_class.polymorphic = true end end
# File lib/mongoid/association/relatable.rb, line 324 def setup_index! @owner_class.index(index_spec, background: true) if indexed? end
# File lib/mongoid/association/relatable.rb, line 380 def validate! @options.keys.each do |opt| unless self.class::VALID_OPTIONS.include?(opt) raise Errors::InvalidRelationOption.new(@owner_class, name, opt, self.class::VALID_OPTIONS) end end [name, "#{name}?".to_sym, "#{name}=".to_sym].each do |n| if Mongoid.destructive_fields.include?(n) raise Errors::InvalidRelation.new(@owner_class, n) end end end