Class: Mongoid::Relations::Referenced::Many
- Includes:
- Batch
- Defined in:
- lib/mongoid/relations/referenced/many.rb
Overview
This class defines the behaviour for all relations that are a one-to-many between documents in different collections.
Direct Known Subclasses
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
Get the standard criteria used for querying this relation.
-
.eager_load(metadata, ids) ⇒ Criteria
Eager load the relation based on the criteria.
-
.embedded? ⇒ false
Returns true if the relation is an embedded one.
-
.foreign_key_default ⇒ nil
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? ⇒ false
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) ⇒ 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.
-
#create(attributes = nil, options = {}, type = nil, &block) ⇒ Document
Creates a new document on the references many relation.
-
#create!(attributes = nil, options = {}, type = nil, &block) ⇒ Document
Creates a new document on the references many relation.
-
#delete(document) ⇒ Document
Delete the document from the relation.
-
#delete_all(conditions = nil) ⇒ Integer
Deletes all related documents from the database given the supplied conditions.
-
#destroy_all(conditions = nil) ⇒ Integer
Destroys all related documents from the database given the supplied conditions.
-
#each ⇒ Array<Document>
Iterate over each document in the relation and yield to the provided block.
-
#find(*args) ⇒ Document, Criteria
Find the matchind document on the association, either based on id or conditions.
-
#initialize(base, target, metadata) ⇒ Many
constructor
Instantiate a new references_many relation.
-
#nullify ⇒ Object
(also: #nullify_all)
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.
-
#purge ⇒ Many
(also: #clear)
Clear the relation.
-
#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
#blank?, #exists?, #find_or_create_by, #find_or_initialize_by, #nil?, #respond_to?, #scoped, #serializable_hash
Methods inherited from Proxy
Constructor Details
#initialize(base, target, metadata) ⇒ Many
Instantiate a new references_many relation. Will set the foreign key and the base on the inverse object.
267 268 269 270 271 |
# File 'lib/mongoid/relations/referenced/many.rb', line 267 def initialize(base, target, ) init(base, Targets::Enumerable.new(target), ) do raise_mixed if klass. end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Criteria, Object (private)
If the target array does not respond to the supplied method then try to find a named scope or criteria on the class and send the call there.
If the method exists on the array, use the default proxy behavior.
443 444 445 446 447 448 449 450 451 |
# File 'lib/mongoid/relations/referenced/many.rb', line 443 def method_missing(name, *args, &block) if target.respond_to?(name) target.send(name, *args, &block) else klass.send(:with_scope, criteria) do criteria.send(name, *args, &block) end end end |
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.
537 538 539 |
# File 'lib/mongoid/relations/referenced/many.rb', line 537 def builder(base, , object) Builders::Referenced::Many.new(base, , object || []) end |
.criteria(metadata, object, type = nil) ⇒ Criteria
Get the standard criteria used for querying this relation.
553 554 555 |
# File 'lib/mongoid/relations/referenced/many.rb', line 553 def criteria(, object, type = nil) .klass.where(.foreign_key => object) end |
.eager_load(metadata, ids) ⇒ Criteria
Eager load the relation based on the criteria.
568 569 570 571 572 573 574 575 576 577 578 579 |
# File 'lib/mongoid/relations/referenced/many.rb', line 568 def eager_load(, ids) cleared = false klass, foreign_key = .klass, .foreign_key klass.any_in(foreign_key => ids).each do |doc| base_id = doc.send(foreign_key) unless cleared IdentityMap.clear_many(klass, foreign_key => base_id) cleared = true end IdentityMap.set_many(doc, foreign_key => base_id) end end |
.embedded? ⇒ false
Returns true if the relation is an embedded one. In this case always false.
590 591 592 |
# File 'lib/mongoid/relations/referenced/many.rb', line 590 def false end |
.foreign_key_default ⇒ nil
Get the default value for the foreign key.
602 603 604 |
# File 'lib/mongoid/relations/referenced/many.rb', line 602 def foreign_key_default nil end |
.foreign_key_suffix ⇒ String
Returns the suffix of the foreign key field, either “_id” or “_ids”.
614 615 616 |
# File 'lib/mongoid/relations/referenced/many.rb', line 614 def foreign_key_suffix "_id" end |
.macro ⇒ Symbol
Returns the macro for this relation. Used mostly as a helper in reflection.
625 626 627 |
# File 'lib/mongoid/relations/referenced/many.rb', line 625 def macro :references_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.
651 652 653 |
# File 'lib/mongoid/relations/referenced/many.rb', line 651 def nested_builder(, attributes, ) Builders::NestedAttributes::Many.new(, attributes, ) end |
.path(document) ⇒ Root
Get the path calculator for the supplied document.
665 666 667 |
# File 'lib/mongoid/relations/referenced/many.rb', line 665 def path(document) Mongoid::Atomic::Paths::Root.new(document) end |
.stores_foreign_key? ⇒ false
Tells the caller if this relation is one that stores the foreign key on its own objects.
678 679 680 |
# File 'lib/mongoid/relations/referenced/many.rb', line 678 def stores_foreign_key? false end |
.valid_options ⇒ Array<Symbol>
Get the valid options allowed with this relation.
690 691 692 |
# File 'lib/mongoid/relations/referenced/many.rb', line 690 def [ :as, :autosave, :dependent, :foreign_key, :order ] end |
.validation_default ⇒ true, false
Get the default validation setting for the relation. Determines if by default a validates associated will occur.
703 704 705 |
# File 'lib/mongoid/relations/referenced/many.rb', line 703 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.
31 32 33 34 35 36 37 38 |
# File 'lib/mongoid/relations/referenced/many.rb', line 31 def <<(*args) docs = args.flatten return concat(docs) if docs.size > 1 if doc = docs.first append(doc) doc.save if persistable? && !_assigning? && !doc.validated? end 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.
85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/mongoid/relations/referenced/many.rb', line 85 def build(attributes = {}, = {}, type = nil) if .is_a? Class , type = {}, end Factory.build(type || klass, attributes, ).tap do |doc| append(doc) doc.apply_proc_defaults yield(doc) if block_given? doc.run_callbacks(:build) { doc } end end |
#concat(documents) ⇒ Array<Document>
When performing batch inserts the after callbacks will get executed before the documents have actually been persisted to the database due to an issue with Active Support’s callback system - we cannot explicitly fire the after callbacks by themselves.
Appends an array of documents to the relation. Performs a batch insert of the documents instead of persisting one at a time.
57 58 59 60 61 62 63 64 65 |
# File 'lib/mongoid/relations/referenced/many.rb', line 57 def concat(documents) batched do documents.each do |doc| next unless doc append(doc) doc.save if persistable? end end end |
#create(attributes = nil, options = {}, type = nil) ⇒ Document #create(attributes = nil, type = nil) ⇒ Document
Creates a new document on the references many relation. This will save the document if the parent has been persisted.
117 118 119 120 121 |
# File 'lib/mongoid/relations/referenced/many.rb', line 117 def create(attributes = nil, = {}, type = nil, &block) build(attributes, , type, &block).tap do |doc| base.persisted? ? doc.save : raise_unsaved(doc) end end |
#create!(attributes = nil, options = {}, type = nil) ⇒ Document #create!(attributes = nil, type = nil) ⇒ Document
Creates a new document on the references many relation. This will save the document if the parent has been persisted and will raise an error if validation fails.
144 145 146 147 148 |
# File 'lib/mongoid/relations/referenced/many.rb', line 144 def create!(attributes = nil, = {}, type = nil, &block) build(attributes, , type, &block).tap do |doc| base.persisted? ? doc.save! : raise_unsaved(doc) end 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.
162 163 164 165 166 167 168 169 |
# File 'lib/mongoid/relations/referenced/many.rb', line 162 def delete(document) target.delete(document) do |doc| if doc unbind_one(doc) cascade!(doc) end end end |
#delete_all(conditions = nil) ⇒ Integer
Deletes all related documents from the database given the supplied conditions.
185 186 187 |
# File 'lib/mongoid/relations/referenced/many.rb', line 185 def delete_all(conditions = nil) remove_all(conditions, :delete_all) end |
#destroy_all(conditions = nil) ⇒ Integer
Destroys all related documents from the database given the supplied conditions.
203 204 205 |
# File 'lib/mongoid/relations/referenced/many.rb', line 203 def destroy_all(conditions = nil) remove_all(conditions, :destroy_all) end |
#each ⇒ Array<Document>
This will load the entire relation into memory.
Iterate over each document in the relation and yield to the provided block.
220 221 222 |
# File 'lib/mongoid/relations/referenced/many.rb', line 220 def each target.each { |doc| yield(doc) if block_given? } end |
#find(*args) ⇒ Document, Criteria
This will keep matching documents in memory for iteration later.
Find the matchind document on the association, either based on id or conditions.
250 251 252 253 254 |
# File 'lib/mongoid/relations/referenced/many.rb', line 250 def find(*args) matching = criteria.find(*args) Array(matching).each { |doc| target.push(doc) } matching end |
#nullify ⇒ Object Also known as: nullify_all
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.
281 282 283 284 285 286 |
# File 'lib/mongoid/relations/referenced/many.rb', line 281 def nullify criteria.update(.foreign_key => nil) target.clear do |doc| unbind_one(doc) end end |
#purge ⇒ Many Also known as: clear
Clear the relation. Will delete the documents from the db if they are already persisted.
298 299 300 301 302 303 304 305 306 307 308 |
# File 'lib/mongoid/relations/referenced/many.rb', line 298 def purge unless .destructive? nullify else criteria.delete_all target.clear do |doc| unbind_one(doc) doc.destroyed = true end end 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.
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 |
# File 'lib/mongoid/relations/referenced/many.rb', line 323 def substitute(replacement) tap do |proxy| if replacement new_docs, docs = replacement.compact.uniq, [] new_ids = new_docs.map { |doc| doc.id } remove_not_in(new_ids) new_docs.each do |doc| docs.push(doc) if doc.send(.foreign_key) != base.id end proxy.concat(docs) else proxy.purge end end end |
#unscoped ⇒ Criteria
Get a criteria for the documents without the default scoping applied.
348 349 350 351 352 |
# File 'lib/mongoid/relations/referenced/many.rb', line 348 def unscoped klass.unscoped.where( .foreign_key => Conversions.flag(base.id, ) ) end |