class Mongoid::Association::Referenced::HasAndBelongsToMany
The HasAndBelongsToMany
type association.
@since 7.0
Constants
- ASSOCIATION_OPTIONS
The options available for this type of association, in addition to the common ones.
@return [ Array<Symbol> ] The extra valid options.
@since 7.0
- FOREIGN_KEY_FIELD_TYPE
The type of the field holding the foreign key.
@return [ Array ]
@since 7.0
- FOREIGN_KEY_SUFFIX
The default foreign key suffix.
@return [ String ] ‘_ids’
@since 7.0
- VALID_OPTIONS
The complete list of valid options for this association, including the shared ones.
@return [ Array<Symbol> ] The valid options.
@since 7.0
Public Instance Methods
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.
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 163 def bindable?(doc) forced_nil_inverse? || (!!inverse && doc.fields.keys.include?(foreign_key)) end
The criteria used for querying this association.
@return [ Mongoid::Criteria
] The criteria used for querying this association.
@since 7.0
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 137 def criteria(base, id_list = nil) query_criteria(id_list || base.send(foreign_key)) end
Is this association type embedded?
@return [ false ] Always false.
@since 7.0
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 88 def embedded?; false; end
Are ids only saved on this side of the association?
@return [ true, false ] Whether this association has a forced nil inverse.
@since 7.0
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 102 def forced_nil_inverse? @forced_nil_inverse ||= @options.key?(:inverse_of) && !@options[:inverse_of] end
Get the foreign key field for saving the association reference.
@return [ String ] The foreign key field for saving the association reference.
@since 7.0
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 127 def foreign_key @foreign_key ||= @options[:foreign_key] ? @options[:foreign_key].to_s : default_foreign_key_field end
Get the foreign key field on the inverse.
@return [ String ] The foreign key field for saving the association reference
on the inverse side.
@since 7.0
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 147 def inverse_foreign_key if @options.key?(:inverse_foreign_key) @options[:inverse_foreign_key] elsif @options.key?(:inverse_of) inverse_of ? "#{inverse_of.to_s.singularize}#{FOREIGN_KEY_SUFFIX}" : nil else "#{inverse_class_name.demodulize.underscore}#{FOREIGN_KEY_SUFFIX}" end end
Get the foreign key setter on the inverse.
@return [ String ] The foreign key setter for saving the association reference
on the inverse side.
@since 7.0
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 173 def inverse_foreign_key_setter @inverse_foreign_key_setter ||= "#{inverse_foreign_key}=" if inverse_foreign_key end
The nested builder object.
@param [ Hash ] attributes The attributes to use to build the association object. @param [ Hash ] options The options for the association.
@return [ Association::Nested::One
] The Nested
Builder object.
@since 7.0
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 185 def nested_builder(attributes, options) Nested::Many.new(self, attributes, options) end
Get the path calculator for the supplied document.
@example Get the path calculator.
association.path(document)
@param [ Document
] document The document to calculate on.
@return [ Root ] The root atomic path calculator.
@since 2.1.0
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 199 def path(document) Mongoid::Atomic::Paths::Root.new(document) end
Get the association proxy class for this association type.
@return [ Association::HasAndBelongsToMany::Proxy ] The proxy class.
@since 7.0
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 118 def relation Proxy end
The list of association complements.
@return [ Array<Association> ] The association complements.
@since 7.0
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 69 def relation_complements @relation_complements ||= [ self.class ].freeze end
Setup the instance methods, fields, etc. on the association owning class.
@return [ self ]
@since 7.0
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 78 def setup! setup_instance_methods! self end
Does this association type store the foreign key?
@return [ true ] Always true.
@since 7.0
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 111 def stores_foreign_key?; true; end
The default for validation the association object.
@return [ false ] Always false.
@since 7.0
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 95 def validation_default; true; end
Private Instance Methods
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 259 def create_foreign_key_field! @owner_class.field( foreign_key, type: FOREIGN_KEY_FIELD_TYPE, identity: true, overwrite: true, association: self, default: nil ) end
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 227 def default_foreign_key_field @default_foreign_key_field ||= "#{name.to_s.singularize}#{FOREIGN_KEY_SUFFIX}" end
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 223 def default_primary_key PRIMARY_KEY_DEFAULT end
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 270 def determine_inverses(other) matches = (other || relation_class).relations.values.select do |rel| relation_complements.include?(rel.class) && rel.relation_class_name == inverse_class_name end if matches.size > 1 raise Errors::AmbiguousRelationship.new(relation_class, @owner_class, name, matches) end matches.collect { |m| m.name } unless matches.blank? end
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 219 def index_spec { key => 1 } end
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 290 def query_criteria(id_list) crit = relation_class.all_of(primary_key => {"$in" => id_list || []}) with_ordering(crit) end
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 205 def setup_instance_methods! define_getter! define_setter! define_dependency! define_existence_check! define_autosaver! define_counter_cache_callbacks! create_foreign_key_field! setup_index! setup_syncing! @owner_class.validates_associated(name) if validate? self end
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 231 def setup_syncing! unless forced_nil_inverse? synced_save synced_destroy end end
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 238 def synced_destroy assoc = self inverse_class.set_callback( :destroy, :after ) do |doc| doc.remove_inverse_keys(assoc) end end
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 248 def synced_save assoc = self inverse_class.set_callback( :save, :after, if: ->(doc){ doc._syncable?(assoc) } ) do |doc| doc.update_inverse_keys(assoc) end end
# File lib/mongoid/association/referenced/has_and_belongs_to_many.rb, line 282 def with_ordering(criteria) if order criteria.order_by(order) else criteria end end