Class: Mongoid::Relations::Referenced::ManyToMany
- Defined in:
- lib/mongoid/relations/referenced/many_to_many.rb
Overview
This class defines the behaviour for all relations that are a many-to-many between documents in different collections.
Instance Attribute Summary
Attributes inherited from Proxy
#base, #loaded, #metadata, #target
Class Method Summary collapse
-
.builder(base, meta, object) ⇒ Builder
Return the builder that is responsible for generating the documents that will be used by this relation.
-
.criteria(metadata, object, type = nil) ⇒ Criteria
Create the standard criteria for this relation given the supplied metadata and object.
-
.eager_load(metadata, ids) ⇒ Criteria
Get the criteria that is used to eager load a relation of this type.
-
.embedded? ⇒ false
Returns true if the relation is an embedded one.
-
.foreign_key(name) ⇒ String
Get the foreign key for the provided name.
-
.foreign_key_default ⇒ Array
Get the default value for the foreign key.
-
.foreign_key_suffix ⇒ String
Returns the suffix of the foreign key field, either “_id” or “_ids”.
-
.macro ⇒ Symbol
Returns the macro for this relation.
-
.nested_builder(metadata, attributes, options) ⇒ NestedBuilder
Return the nested builder that is responsible for generating the documents that will be used by this relation.
-
.path(document) ⇒ Root
Get the path calculator for the supplied document.
-
.stores_foreign_key? ⇒ true
Tells the caller if this relation is one that stores the foreign key on its own objects.
-
.valid_options ⇒ Array<Symbol>
Get the valid options allowed with this relation.
-
.validation_default ⇒ true, false
Get the default validation setting for the relation.
Instance Method Summary collapse
-
#<<(*args) ⇒ Array<Document>
(also: #push)
Appends a document or array of documents to the relation.
-
#build(attributes = {}, options = {}, type = nil) {|doc| ... } ⇒ Document
(also: #new)
Build a new document from the attributes and append it to this relation without saving.
-
#concat(documents) ⇒ Array<Document>
Appends an array of documents to the relation.
-
#delete(document) ⇒ Document
Delete the document from the relation.
-
#nullify ⇒ Object
(also: #nullify_all, #clear, #purge)
Removes all associations between the base document and the target documents by deleting the foreign keys and the references, orphaning the target documents in the process.
-
#substitute(replacement) ⇒ Many
Substitutes the supplied target documents for the existing documents in the relation.
-
#unscoped ⇒ Criteria
Get a criteria for the documents without the default scoping applied.
Methods inherited from Many
#delete_all, #destroy_all, #each, #exists?, #find, #initialize
Methods inherited from Many
#blank?, #create, #create!, #find_or_create_by, #find_or_initialize_by, #nil?, #respond_to?, #scoped, #serializable_hash
Methods inherited from Proxy
apply_ordering, eager_load_ids, #init, #klass, #reset_unloaded, #substitutable, #with
Methods included from Marshalable
Constructor Details
This class inherits a constructor from Mongoid::Relations::Referenced::Many
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Mongoid::Relations::Referenced::Many
Class Method Details
.builder(base, meta, object) ⇒ Builder
Return the builder that is responsible for generating the documents that will be used by this relation.
298 299 300 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 298 def builder(base, , object) Builders::Referenced::ManyToMany.new(base, , object) end |
.criteria(metadata, object, type = nil) ⇒ Criteria
Create the standard criteria for this relation given the supplied metadata and object.
315 316 317 318 319 320 321 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 315 def criteria(, object, type = nil) apply_ordering( .klass.all_of( .primary_key => { "$in" => object || [] } ), ) end |
.eager_load(metadata, ids) ⇒ Criteria
Get the criteria that is used to eager load a relation of this type.
335 336 337 338 339 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 335 def eager_load(, ids) .klass.any_in(_id: ids).each do |doc| IdentityMap.set(doc) end end |
.embedded? ⇒ false
Returns true if the relation is an embedded one. In this case always false.
350 351 352 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 350 def false end |
.foreign_key(name) ⇒ String
Get the foreign key for the provided name.
364 365 366 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 364 def foreign_key(name) "#{name.to_s.singularize}#{foreign_key_suffix}" end |
.foreign_key_default ⇒ Array
Get the default value for the foreign key.
376 377 378 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 376 def foreign_key_default [] end |
.foreign_key_suffix ⇒ String
Returns the suffix of the foreign key field, either “_id” or “_ids”.
388 389 390 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 388 def foreign_key_suffix "_ids" end |
.macro ⇒ Symbol
Returns the macro for this relation. Used mostly as a helper in reflection.
399 400 401 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 399 def macro :has_and_belongs_to_many end |
.nested_builder(metadata, attributes, options) ⇒ NestedBuilder
Return the nested builder that is responsible for generating the documents that will be used by this relation.
425 426 427 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 425 def nested_builder(, attributes, ) Builders::NestedAttributes::Many.new(, attributes, ) end |
.path(document) ⇒ Root
Get the path calculator for the supplied document.
439 440 441 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 439 def path(document) Mongoid::Atomic::Paths::Root.new(document) end |
.stores_foreign_key? ⇒ true
Tells the caller if this relation is one that stores the foreign key on its own objects.
452 453 454 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 452 def stores_foreign_key? true end |
.valid_options ⇒ Array<Symbol>
Get the valid options allowed with this relation.
464 465 466 467 468 469 470 471 472 473 474 475 476 477 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 464 def [ :after_add, :after_remove, :autosave, :before_add, :before_remove, :dependent, :foreign_key, :index, :order, :primary_key ] end |
.validation_default ⇒ true, false
Get the default validation setting for the relation. Determines if by default a validates associated will occur.
488 489 490 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 488 def validation_default true end |
Instance Method Details
#<<(*args) ⇒ Array<Document> Also known as: push
Appends a document or array of documents to the relation. Will set the parent and update the index in the process.
27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 27 def <<(*args) docs = args.flatten return concat(docs) if docs.size > 1 if doc = docs.first append(doc) base.add_to_set(foreign_key, doc.send(.primary_key)) if child_persistable?(doc) doc.save end end unsynced(base, foreign_key) and self end |
#build(attributes = {}, options = {}, type = nil) ⇒ Document #build(attributes = {}, type = nil) ⇒ Document Also known as: new
Build a new document from the attributes and append it to this relation without saving.
93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 93 def build(attributes = {}, = {}, type = nil) if .is_a? Class , type = {}, end doc = Factory.build(type || klass, attributes, ) base.send(foreign_key).push(doc.id) append(doc) doc.apply_post_processed_defaults unsynced(doc, inverse_foreign_key) yield(doc) if block_given? doc end |
#concat(documents) ⇒ Array<Document>
Appends an array of documents to the relation. Performs a batch insert of the documents instead of persisting one at a time.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 52 def concat(documents) ids, docs, inserts = {}, [], [] documents.each do |doc| next unless doc append(doc) if persistable? || _creating? ids[doc.id] = true save_or_delay(doc, docs, inserts) else existing = base.send(foreign_key) unless existing.include?(doc.id) existing.push(doc.id) and unsynced(base, foreign_key) end end end if persistable? || _creating? base.push_all(foreign_key, ids.keys) end persist_delayed(docs, inserts) self end |
#delete(document) ⇒ Document
Delete the document from the relation. This will set the foreign key on the document to nil. If the dependent options on the relation are :delete or :destroy the appropriate removal will occur.
120 121 122 123 124 125 126 127 128 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 120 def delete(document) doc = super if doc && persistable? base.pull(foreign_key, doc.send(.primary_key)) target._unloaded = criteria unsynced(base, foreign_key) end doc end |
#nullify ⇒ Object Also known as: nullify_all, clear, purge
Removes all associations between the base document and the target documents by deleting the foreign keys and the references, orphaning the target documents in the process.
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 138 def nullify target.each do |doc| execute_callback :before_remove, doc end unless .forced_nil_inverse? criteria.pull(inverse_foreign_key, base.id) end if persistable? base.set( foreign_key, base.send(foreign_key).clear ) end after_remove_error = nil many_to_many = target.clear do |doc| unbind_one(doc) unless .forced_nil_inverse? doc.changed_attributes.delete(inverse_foreign_key) end begin execute_callback :after_remove, doc rescue => e after_remove_error = e end end raise after_remove_error if after_remove_error many_to_many end |
#substitute(replacement) ⇒ Many
Substitutes the supplied target documents for the existing documents in the relation. If the new target is nil, perform the necessary deletion.
person.preferences.substitute([ new_post ])
182 183 184 185 186 187 188 189 190 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 182 def substitute(replacement) purge unless replacement.blank? push(replacement.compact.uniq) else reset_unloaded end self end |
#unscoped ⇒ Criteria
Get a criteria for the documents without the default scoping applied.
201 202 203 |
# File 'lib/mongoid/relations/referenced/many_to_many.rb', line 201 def unscoped klass.unscoped.any_in(_id: base.send(foreign_key)) end |