Class: Mongoid::Relations::Embedded::Many
- Includes:
- Atomic
- Defined in:
- lib/mongoid/relations/embedded/many.rb
Overview
This class handles the behaviour for a document that embeds many other documents within in it as an array.
Constant Summary
Constants included from Atomic
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.
-
.embedded? ⇒ true
Returns true if the relation is an embedded one.
-
.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) ⇒ Mongoid::Atomic::Paths::Embedded::Many
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) ⇒ Object
(also: #push)
Appends a document or array of documents to the relation.
-
#as_document ⇒ Array<Hash>
Get this relation as as its representation in the database.
-
#build(attributes = {}, options = {}, type = nil) ⇒ Document
(also: #new)
Builds a new document in the relation and appends it to the target.
-
#clear ⇒ Many
Clear the relation.
-
#concat(documents) ⇒ Array<Document>
Appends an array of documents to the relation.
-
#count ⇒ Integer
Returns a count of the number of documents in the association that have actually been persisted to the database.
-
#create(attributes = {}, options = {}, type = nil, &block) ⇒ Document
Create a new document in the relation.
-
#create!(attributes = {}, options = {}, type = nil, &block) ⇒ Document
Create a new document in the relation.
-
#delete(document) ⇒ Document?
Delete the supplied document from the target.
-
#delete_all(conditions = {}) ⇒ Integer
Delete all the documents in the association without running callbacks.
-
#destroy_all(conditions = {}) ⇒ Integer
Destroy all the documents in the association whilst running callbacks.
-
#find(*args) ⇒ Array<Document>, Document
Finds a document in this association through several different methods.
-
#in_memory ⇒ Array<Document>
Get all the documents in the relation that are loaded into memory.
-
#initialize(base, target, metadata) ⇒ Many
constructor
Instantiate a new embeds_many relation.
-
#substitute(replacement) ⇒ Many
Substitutes the supplied target documents for the existing documents in the relation.
-
#unscoped ⇒ Criteria
Return the relation with all previous scoping removed.
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 embeds_many relation.
268 269 270 271 272 273 274 275 276 277 |
# File 'lib/mongoid/relations/embedded/many.rb', line 268 def initialize(base, target, ) init(base, target, ) do target.each_with_index do |doc, index| integrate(doc) doc._index = index end @_unscoped = target.dup @target = scope(target) 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.
442 443 444 445 446 447 |
# File 'lib/mongoid/relations/embedded/many.rb', line 442 def method_missing(name, *args, &block) return super if target.respond_to?(name) klass.send(:with_scope, criteria) do criteria.send(name, *args, &block) 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.
558 559 560 |
# File 'lib/mongoid/relations/embedded/many.rb', line 558 def builder(base, , object) Builders::Embedded::Many.new(base, , object) end |
.embedded? ⇒ true
Returns true if the relation is an embedded one. In this case always true.
571 572 573 |
# File 'lib/mongoid/relations/embedded/many.rb', line 571 def true end |
.macro ⇒ Symbol
Returns the macro for this relation. Used mostly as a helper in reflection.
584 585 586 |
# File 'lib/mongoid/relations/embedded/many.rb', line 584 def macro :embeds_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.
610 611 612 |
# File 'lib/mongoid/relations/embedded/many.rb', line 610 def nested_builder(, attributes, ) Builders::NestedAttributes::Many.new(, attributes, ) end |
.path(document) ⇒ Mongoid::Atomic::Paths::Embedded::Many
Get the path calculator for the supplied document.
625 626 627 |
# File 'lib/mongoid/relations/embedded/many.rb', line 625 def path(document) Mongoid::Atomic::Paths::Embedded::Many.new(document) end |
.stores_foreign_key? ⇒ false
Tells the caller if this relation is one that stores the foreign key on its own objects.
638 639 640 |
# File 'lib/mongoid/relations/embedded/many.rb', line 638 def stores_foreign_key? false end |
.valid_options ⇒ Array<Symbol>
Get the valid options allowed with this relation.
650 651 652 |
# File 'lib/mongoid/relations/embedded/many.rb', line 650 def [ :as, :cascade_callbacks, :cyclic, :order, :versioned ] end |
.validation_default ⇒ true, false
Get the default validation setting for the relation. Determines if by default a validates associated will occur.
663 664 665 |
# File 'lib/mongoid/relations/embedded/many.rb', line 663 def validation_default true end |
Instance Method Details
#<<(*args) ⇒ Object 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.
21 22 23 24 25 26 27 28 |
# File 'lib/mongoid/relations/embedded/many.rb', line 21 def <<(*args) docs = args.flatten return concat(docs) if docs.size > 1 if doc = docs.first append(doc) doc.save if persistable? && !_assigning? end end |
#as_document ⇒ Array<Hash>
Get this relation as as its representation in the database.
39 40 41 42 43 44 45 |
# File 'lib/mongoid/relations/embedded/many.rb', line 39 def as_document [].tap do |attributes| _unscoped.each do |doc| attributes.push(doc.as_document) end end end |
#build(attributes = {}, options = {}, type = nil) ⇒ Document #build(attributes = {}, type = nil) ⇒ Document Also known as: new
Builds a new document in the relation and appends it to the target. Takes an optional type if you want to specify a subclass.
89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/mongoid/relations/embedded/many.rb', line 89 def build(attributes = {}, = {}, type = nil) if .is_a? Class , type = {}, end Factory.build(type || .klass, attributes, ).tap do |doc| doc.identify append(doc) doc.apply_proc_defaults yield(doc) if block_given? doc.run_callbacks(:build) { doc } end end |
#clear ⇒ Many
Clear the relation. Will delete the documents from the db if they are already persisted.
111 112 113 114 115 116 117 118 |
# File 'lib/mongoid/relations/embedded/many.rb', line 111 def clear tap do |proxy| atomically(:$unset) do proxy.delete_all _unscoped.clear end 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.
63 64 65 66 67 68 69 70 71 |
# File 'lib/mongoid/relations/embedded/many.rb', line 63 def concat(documents) atomically(:$pushAll) do documents.each do |doc| next unless doc append(doc) doc.save if persistable? end end end |
#count ⇒ Integer
Returns a count of the number of documents in the association that have actually been persisted to the database.
Use #size if you want the total number of documents.
130 131 132 |
# File 'lib/mongoid/relations/embedded/many.rb', line 130 def count target.select { |doc| doc.persisted? }.size end |
#create(attributes = {}, options = {}, type = nil) ⇒ Document #create(attributes = {}, type = nil) ⇒ Document
Create a new document in the relation. This is essentially the same as doing a #build then #save on the new document.
150 151 152 |
# File 'lib/mongoid/relations/embedded/many.rb', line 150 def create(attributes = {}, = {}, type = nil, &block) build(attributes, , type, &block).tap { |doc| doc.save } end |
#create!(attributes = {}, options = {}, type = nil) ⇒ Document #create!(attributes = {}, type = nil) ⇒ Document
Create a new document in the relation. This is essentially the same as doing a #build then #save on the new document. If validation failed on the document an error will get raised.
173 174 175 |
# File 'lib/mongoid/relations/embedded/many.rb', line 173 def create!(attributes = {}, = {}, type = nil, &block) build(attributes, , type, &block).tap { |doc| doc.save! } end |
#delete(document) ⇒ Document?
Delete the supplied document from the target. This method is proxied in order to reindex the array after the operation occurs.
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/mongoid/relations/embedded/many.rb', line 188 def delete(document) target.delete_one(document).tap do |doc| _unscoped.delete_one(doc) if doc && !_binding? if _assigning? if doc.paranoid? doc.destroy(:suppress => true) else base.add_atomic_pull(doc) end else doc.delete(:suppress => true) unbind_one(doc) end end reindex end end |
#delete_all(conditions = {}) ⇒ Integer
Delete all the documents in the association without running callbacks.
218 219 220 |
# File 'lib/mongoid/relations/embedded/many.rb', line 218 def delete_all(conditions = {}) atomically(:$pull) { remove_all(conditions, :delete) } end |
#destroy_all(conditions = {}) ⇒ Integer
Destroy all the documents in the association whilst running callbacks.
233 234 235 |
# File 'lib/mongoid/relations/embedded/many.rb', line 233 def destroy_all(conditions = {}) atomically(:$pull) { remove_all(conditions, :destroy) } end |
#find(*args) ⇒ Array<Document>, Document
Finds a document in this association through several different methods.
254 255 256 |
# File 'lib/mongoid/relations/embedded/many.rb', line 254 def find(*args) criteria.find(*args) end |
#in_memory ⇒ Array<Document>
Get all the documents in the relation that are loaded into memory.
287 288 289 |
# File 'lib/mongoid/relations/embedded/many.rb', line 287 def in_memory target end |
#substitute(replacement) ⇒ Many
Substitutes the supplied target documents for the existing documents in the relation.
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
# File 'lib/mongoid/relations/embedded/many.rb', line 303 def substitute(replacement) tap do |proxy| if replacement.blank? if _assigning? && !proxy.empty? base.atomic_unsets.push(_unscoped.first.atomic_path) end proxy.clear else atomically(:$set) do base.delayed_atomic_sets.clear unless _assigning? if replacement.first.is_a?(Hash) replacement = replacement.map do |doc| attributes = { :metadata => , :_parent => base } attributes.merge!(doc) Factory.build(klass, attributes) end end docs = replacement.compact proxy.target = docs self._unscoped = docs.dup proxy.target.each_with_index do |doc, index| integrate(doc) doc._index = index doc.save if base.persisted? && !_assigning? end if _assigning? name = _unscoped.first.atomic_path base.delayed_atomic_sets[name].try(:clear) base._children.each do |child| child.delayed_atomic_sets.clear end base.instance_variable_set(:@_children, nil) base.delayed_atomic_sets[name] = proxy.as_document end end end end end |
#unscoped ⇒ Criteria
Return the relation with all previous scoping removed. This is the exact representation of the docs in the database.
351 352 353 354 355 |
# File 'lib/mongoid/relations/embedded/many.rb', line 351 def unscoped klass.criteria(true, false).tap do |criterion| criterion.documents = _unscoped end end |