Class: Mongoid::Association::Embedded::EmbedsMany::Proxy
- Extended by:
- Forwardable, ClassMethods
- Includes:
- Batchable
- Defined in:
- lib/mongoid/association/embedded/embeds_many/proxy.rb
Overview
Transparent proxy for embeds_many associations. An instance of this class is returned when calling the association getter method on the parent document. This class inherits from Mongoid::Association::Proxy and forwards most of its methods to the target of the association, i.e. the array of child documents.
Defined Under Namespace
Modules: ClassMethods
Constant Summary
Constants inherited from Proxy
Instance Attribute Summary
Attributes inherited from Proxy
#_association, #_base, #_target
Instance Method Summary collapse
-
#<<(*args) ⇒ Object
(also: #push)
Appends a document or array of documents to the association.
-
#_remove(document) ⇒ Object
private
Removes a single document from the collection *in memory only*.
-
#as_document ⇒ Array<Hash>
Get this association as as its representation in the database.
-
#build(attributes = {}, type = nil) ⇒ Document
(also: #new)
Builds a new document in the association and appends it to the target.
-
#clear ⇒ self
Clear the association.
-
#concat(docs) ⇒ Array<Document>
Appends an array of documents to the association.
-
#count(*args, &block) ⇒ Integer
Returns a count of the number of documents in the association that have actually been persisted to the database.
-
#delete(document) ⇒ Document | nil
(also: #delete_one)
Delete the supplied document from the target.
-
#delete_all(conditions = {}) ⇒ Integer
Delete all the documents in the association without running callbacks.
-
#delete_if ⇒ EmbedsMany::Proxy | Enumerator
Delete all the documents for which the provided block returns true.
-
#destroy_all(conditions = {}) ⇒ Integer
Destroy all the documents in the association whilst running callbacks.
-
#exists?(id_or_conditions = :none) ⇒ true | false
Determine if any documents in this association exist in the database.
-
#initialize(base, target, association) ⇒ Many
constructor
Instantiate a new embeds_many association.
-
#pop(count = nil) ⇒ Document | Array<Document> | nil
Pop documents off the association.
-
#shift(count = nil) ⇒ Document | Array<Document> | nil
Shift documents off the association.
-
#substitute(docs) ⇒ Many
Substitutes the supplied target documents for the existing documents in the relation.
-
#unscoped ⇒ Criteria
Return the association with all previous scoping removed.
Methods included from ClassMethods
eager_loader, embedded?, foreign_key_suffix
Methods included from Batchable
#batch_clear, #batch_insert, #batch_remove, #batch_replace
Methods included from Positional
Methods inherited from Many
#blank?, #cache_version, #create, #create!, #find_or_create_by, #find_or_create_by!, #find_or_initialize_by, #nil?, #respond_to?, #scoped, #serializable_hash
Methods inherited from Proxy
apply_ordering, #extend_proxies, #klass, #reset_unloaded, #substitutable
Methods included from Marshalable
Constructor Details
#initialize(base, target, association) ⇒ Many
Instantiate a new embeds_many association.
70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/mongoid/association/embedded/embeds_many/proxy.rb', line 70 def initialize(base, target, association) super do _target.each_with_index do |doc, index| integrate(doc) doc._index = index end update_attributes_hash @_unscoped = _target.dup @_target = scope(_target) end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing ⇒ 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.
TODO: make sure we are consistently using respond_to_missing
anywhere we define method_missing.
rubocop:disable Style/MissingRespondToMissing
525 526 527 528 529 530 531 |
# File 'lib/mongoid/association/embedded/embeds_many/proxy.rb', line 525 ruby2_keywords def method_missing(name, *args, &block) return super if _target.respond_to?(name) klass.send(:with_scope, criteria) do criteria.public_send(name, *args, &block) end end |
Instance Method Details
#<<(*args) ⇒ Object Also known as: push
Appends a document or array of documents to the association. Will set the parent and update the index in the process.
92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/mongoid/association/embedded/embeds_many/proxy.rb', line 92 def <<(*args) docs = args.flatten return unless docs.any? return concat(docs) if docs.size > 1 docs.first.tap do |doc| append(doc) doc.save if persistable? && !_assigning? end self end |
#_remove(document) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Removes a single document from the collection *in memory only*. It will not persist the change.
239 240 241 242 243 244 |
# File 'lib/mongoid/association/embedded/embeds_many/proxy.rb', line 239 def _remove(document) _target.delete_one(document) _unscoped.delete_one(document) update_attributes_hash reindex end |
#as_document ⇒ Array<Hash>
Get this association as as its representation in the database.
113 114 115 |
# File 'lib/mongoid/association/embedded/embeds_many/proxy.rb', line 113 def as_document as_attributes.collect { |attrs| BSON::Document.new(attrs) } end |
#build(attributes = {}, type = nil) ⇒ Document Also known as: new
Builds a new document in the association and appends it to the target. Takes an optional type if you want to specify a subclass.
141 142 143 144 145 146 147 148 149 150 |
# File 'lib/mongoid/association/embedded/embeds_many/proxy.rb', line 141 def build(attributes = {}, type = nil) Factory.execute_build(type || _association.klass, attributes, execute_callbacks: false).tap do |doc| append(doc) doc.apply_post_processed_defaults yield doc if block_given? doc.run_pending_callbacks doc.run_callbacks(:build) { doc } _base._reset_memoized_descendants! end end |
#clear ⇒ self
Clear the association. Will delete the documents from the db if they are already persisted.
If the host document is not persisted but its _id matches a persisted document, calling #clear on an association will remove the association’s documents from the database even though the set of documents in the application (as loaded in the host) is different from what is in the database, and the host may not contain any persisted documents in the association either.
168 169 170 171 172 |
# File 'lib/mongoid/association/embedded/embeds_many/proxy.rb', line 168 def clear batch_clear(_target.dup) update_attributes_hash self end |
#concat(docs) ⇒ Array<Document>
Appends an array of documents to the association. Performs a batch insert of the documents instead of persisting one at a time.
126 127 128 129 |
# File 'lib/mongoid/association/embedded/embeds_many/proxy.rb', line 126 def concat(docs) batch_insert(docs) unless docs.empty? self end |
#count(*args, &block) ⇒ 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.
If args or block are present, #count will delegate to the #count method on target and will include both persisted and non-persisted documents.
196 197 198 199 200 |
# File 'lib/mongoid/association/embedded/embeds_many/proxy.rb', line 196 def count(*args, &block) return _target.count(*args, &block) if args.any? || block _target.count(&:persisted?) end |
#delete(document) ⇒ Document | nil Also known as: delete_one
Delete the supplied document from the target. This method is proxied in order to reindex the array after the operation occurs.
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/mongoid/association/embedded/embeds_many/proxy.rb', line 211 def delete(document) execute_callbacks_around(:remove, document) do _target.delete_one(document).tap do |doc| if doc && !_binding? _unscoped.delete_one(doc) if _assigning? _base.add_atomic_pull(doc) else doc.delete(suppress: true) unbind_one(doc) end update_attributes_hash end reindex end end end |
#delete_all(conditions = {}) ⇒ Integer
Delete all the documents in the association without running callbacks.
257 258 259 |
# File 'lib/mongoid/association/embedded/embeds_many/proxy.rb', line 257 def delete_all(conditions = {}) remove_all(conditions, :delete) end |
#delete_if ⇒ EmbedsMany::Proxy | Enumerator
Delete all the documents for which the provided block returns true.
270 271 272 273 274 275 276 |
# File 'lib/mongoid/association/embedded/embeds_many/proxy.rb', line 270 def delete_if return super unless block_given? _target.dup.each { |doc| delete(doc) if yield doc } self end |
#destroy_all(conditions = {}) ⇒ Integer
Destroy all the documents in the association whilst running callbacks.
289 290 291 |
# File 'lib/mongoid/association/embedded/embeds_many/proxy.rb', line 289 def destroy_all(conditions = {}) remove_all(conditions, :destroy) end |
#exists?(id_or_conditions = :none) ⇒ true | false
Determine if any documents in this association exist in the database.
309 310 311 312 313 314 315 316 |
# File 'lib/mongoid/association/embedded/embeds_many/proxy.rb', line 309 def exists?(id_or_conditions = :none) case id_or_conditions when :none then _target.any?(&:persisted?) when nil, false then false when Hash then where(id_or_conditions).any?(&:persisted?) else where(_id: id_or_conditions).any?(&:persisted?) end end |
#pop(count = nil) ⇒ Document | Array<Document> | nil
Pop documents off the association. This can be a single document or multiples, and will automatically persist the changes.
339 340 341 342 343 344 |
# File 'lib/mongoid/association/embedded/embeds_many/proxy.rb', line 339 def pop(count = nil) return [] if count&.zero? docs = _target.last(count || 1).each { |doc| delete(doc) } (count.nil? || docs.empty?) ? docs.first : docs end |
#shift(count = nil) ⇒ Document | Array<Document> | nil
Shift documents off the association. This can be a single document or multiples, and will automatically persist the changes.
359 360 361 362 363 364 |
# File 'lib/mongoid/association/embedded/embeds_many/proxy.rb', line 359 def shift(count = nil) return [] if count&.zero? docs = _target.first(count || 1).each { |doc| delete(doc) } (count.nil? || docs.empty?) ? docs.first : docs end |
#substitute(docs) ⇒ Many
Substitutes the supplied target documents for the existing documents in the relation.
375 376 377 378 379 |
# File 'lib/mongoid/association/embedded/embeds_many/proxy.rb', line 375 def substitute(docs) batch_replace(docs) update_attributes_hash self end |
#unscoped ⇒ Criteria
Return the association with all previous scoping removed. This is the exact representation of the docs in the database.
388 389 390 391 392 393 |
# File 'lib/mongoid/association/embedded/embeds_many/proxy.rb', line 388 def unscoped criterion = klass.unscoped criterion. = true criterion.documents = _unscoped.delete_if(&:marked_for_destruction?) criterion end |