Class: Mongoid::Association::Referenced::HasMany::Targets::Enumerable
- Inherits:
-
Object
- Object
- Mongoid::Association::Referenced::HasMany::Targets::Enumerable
- Includes:
- Enumerable
- Defined in:
- lib/mongoid/association/referenced/has_many/enumerable.rb
Overview
This class is the wrapper for all relational associations that have a target that can be a criteria or array of _loaded documents. This handles both cases or a combination of the two.
Instance Attribute Summary collapse
-
#_added ⇒ Object
The three main instance variables are collections of documents.
-
#_added Documents that have been appended.(Documentsthathavebeenappended.) ⇒ Object
The three main instance variables are collections of documents.
-
#_loaded ⇒ Object
The three main instance variables are collections of documents.
-
#_loaded Persisted documents that have been _loaded.(Persisteddocumentsthathavebeen_loaded.) ⇒ Object
The three main instance variables are collections of documents.
-
#_unloaded ⇒ Object
The three main instance variables are collections of documents.
-
#_unloaded A criteria representing persisted docs.(Acriteriarepresentingpersisteddocs.) ⇒ Object
The three main instance variables are collections of documents.
Instance Method Summary collapse
-
#<<(document) ⇒ Document
(also: #push)
Append a document to the enumerable.
-
#==(other) ⇒ true, false
Check if the enumerable is equal to the other object.
-
#===(other) ⇒ true, false
Check equality of the enumerable against the provided object for case statements.
-
#_loaded? ⇒ true, false
Has the enumerable been _loaded? This will be true if the criteria has been executed or we manually load the entire thing.
-
#as_json(options = {}) ⇒ Hash
Send #as_json to the entries, without encoding.
-
#clear ⇒ Array<Document>
Clears out all the documents in this enumerable.
-
#clone ⇒ Array<Document>
Clones each document in the enumerable.
-
#delete(document) {|doc| ... } ⇒ Document
Delete the supplied document from the enumerable.
-
#delete_if(&block) ⇒ Array<Document>
Deletes every document in the enumerable for where the block returns true.
-
#each ⇒ true
Iterating over this enumerable has to handle a few different scenarios.
-
#empty? ⇒ true, false
Is the enumerable empty? Will determine if the count is zero based on whether or not it is _loaded.
-
#first(opts = {}) ⇒ Document
Get the first document in the enumerable.
-
#in_memory ⇒ Array<Document>
Return all the documents in the enumerable that have been _loaded or _added.
-
#include?(doc) ⇒ true, false
Does the target include the provided document?.
-
#initialize(target, base = nil, association = nil) ⇒ Enumerable
constructor
Initialize the new enumerable either with a criteria or an array.
-
#inspect ⇒ String
Inspection will just inspect the entries for nice array-style printing.
-
#last(opts = {}) ⇒ Document
Get the last document in the enumerable.
-
#marshal_dump ⇒ Array<Object>
Provides the data needed to Marshal.dump an enumerable proxy.
-
#marshal_load(data) ⇒ Array<Object>
Loads the data needed to Marshal.load an enumerable proxy.
-
#reset ⇒ false
Reset the enumerable back to its persisted state.
-
#reset_unloaded(criteria) ⇒ Object
Resets the underlying unloaded criteria object with a new one.
-
#respond_to?(name, include_private = false) ⇒ true, false
Does this enumerable respond to the provided method?.
-
#size ⇒ Integer
(also: #length)
Gets the total size of this enumerable.
-
#to_json(options = {}) ⇒ String
Send #to_json to the entries.
-
#uniq ⇒ Array<Document>
Return all the unique documents in the enumerable.
Constructor Details
#initialize(target, base = nil, association = nil) ⇒ Enumerable
Initialize the new enumerable either with a criteria or an array.
253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 253 def initialize(target, base = nil, association = nil) @_base = base @_association = association if target.is_a?(Criteria) @_added, @executed, @_loaded, @_unloaded = {}, false, {}, target else @_added, @executed = {}, true @_loaded = target.inject({}) do |_target, doc| _target[doc._id] = doc if doc _target end end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object (private)
498 499 500 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 498 def method_missing(name, *args, &block) entries.send(name, *args, &block) end |
Instance Attribute Details
#_added ⇒ Object
The three main instance variables are collections of documents.
19 20 21 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 19 def _added @_added end |
#_added Documents that have been appended.(Documentsthathavebeenappended.) ⇒ Object
The three main instance variables are collections of documents.
19 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 19 attr_accessor :_added, :_loaded, :_unloaded |
#_loaded ⇒ Object
The three main instance variables are collections of documents.
19 20 21 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 19 def _loaded @_loaded end |
#_loaded Persisted documents that have been _loaded.(Persisteddocumentsthathavebeen_loaded.) ⇒ Object
The three main instance variables are collections of documents.
19 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 19 attr_accessor :_added, :_loaded, :_unloaded |
#_unloaded ⇒ Object
The three main instance variables are collections of documents.
19 20 21 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 19 def _unloaded @_unloaded end |
#_unloaded A criteria representing persisted docs.(Acriteriarepresentingpersisteddocs.) ⇒ Object
The three main instance variables are collections of documents.
19 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 19 attr_accessor :_added, :_loaded, :_unloaded |
Instance Method Details
#<<(document) ⇒ Document Also known as: push
Append a document to the enumerable.
63 64 65 66 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 63 def <<(document) _added[document._id] = document self end |
#==(other) ⇒ true, false
Check if the enumerable is equal to the other object.
33 34 35 36 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 33 def ==(other) return false unless other.respond_to?(:entries) entries == other.entries end |
#===(other) ⇒ true, false
Check equality of the enumerable against the provided object for case statements.
49 50 51 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 49 def ===(other) other.class == Class ? (Array == other || Enumerable == other) : self == other end |
#_loaded? ⇒ true, false
Has the enumerable been _loaded? This will be true if the criteria has been executed or we manually load the entire thing.
358 359 360 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 358 def _loaded? !!@executed end |
#as_json(options = {}) ⇒ Hash
Send #as_json to the entries, without encoding.
472 473 474 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 472 def as_json( = {}) entries.as_json() end |
#clear ⇒ Array<Document>
Clears out all the documents in this enumerable. If passed a block it will yield to each document that is in memory.
84 85 86 87 88 89 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 84 def clear if block_given? in_memory { |doc| yield(doc) } end _loaded.clear and _added.clear end |
#clone ⇒ Array<Document>
This loads all documents into memory.
Clones each document in the enumerable.
101 102 103 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 101 def clone collect { |doc| doc.clone } end |
#delete(document) {|doc| ... } ⇒ Document
Delete the supplied document from the enumerable.
115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 115 def delete(document) doc = (_loaded.delete(document._id) || _added.delete(document._id)) unless doc if _unloaded && _unloaded.where(_id: document._id).exists? yield(document) if block_given? return document end end yield(doc) if block_given? doc end |
#delete_if(&block) ⇒ Array<Document>
This operation loads all documents from the database.
Deletes every document in the enumerable for where the block returns true.
140 141 142 143 144 145 146 147 148 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 140 def delete_if(&block) load_all! deleted = in_memory.select(&block) deleted.each do |doc| _loaded.delete(doc._id) _added.delete(doc._id) end self end |
#each ⇒ true
Iterating over this enumerable has to handle a few different scenarios.
If the enumerable has its criteria _loaded into memory then it yields to all the _loaded docs and all the _added docs.
If the enumerable has not _loaded the criteria then it iterates over the cursor while loading the documents and then iterates over the _added docs.
If no block is passed then it returns an enumerator containing all docs.
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 175 def each unless block_given? return to_enum end if _loaded? _loaded.each_pair do |id, doc| document = _added.delete(doc._id) || doc set_base(document) yield(document) end else unloaded_documents.each do |doc| document = _added.delete(doc._id) || _loaded.delete(doc._id) || doc _loaded[document._id] = document set_base(document) yield(document) end end _added.each_pair do |id, doc| yield(doc) end @executed = true end |
#empty? ⇒ true, false
Is the enumerable empty? Will determine if the count is zero based on whether or not it is _loaded.
208 209 210 211 212 213 214 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 208 def empty? if _loaded? in_memory.count == 0 else _unloaded.count + _added.count == 0 end end |
#first(opts = {}) ⇒ Document
Automatically adding a sort on _id when no other sort is defined on the criteria has the potential to cause bad performance issues. If you experience unexpected poor performance when using #first or #last, use the option { id_sort: :none }. Be aware that #first/#last won’t guarantee order in this case.
Get the first document in the enumerable. Will check the persisted documents first. Does not load the entire enumerable.
235 236 237 238 239 240 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 235 def first(opts = {}) _loaded.try(:values).try(:first) || _added[(ul = _unloaded.try(:first, opts)).try(:id)] || ul || _added.values.try(:first) end |
#in_memory ⇒ Array<Document>
When passed a block it yields to each document.
Return all the documents in the enumerable that have been _loaded or _added.
306 307 308 309 310 311 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 306 def in_memory docs = (_loaded.values + _added.values) docs.each do |doc| yield(doc) if block_given? end end |
#include?(doc) ⇒ true, false
Does the target include the provided document?
277 278 279 280 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 277 def include?(doc) return super unless _unloaded _unloaded.where(_id: doc._id).exists? || _added.has_key?(doc._id) end |
#inspect ⇒ String
Inspection will just inspect the entries for nice array-style printing.
291 292 293 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 291 def inspect entries.inspect end |
#last(opts = {}) ⇒ Document
Automatically adding a sort on _id when no other sort is defined on the criteria has the potential to cause bad performance issues. If you experience unexpected poor performance when using #first or #last, use the option { id_sort: :none }. Be aware that #first/#last won’t guarantee order in this case.
Get the last document in the enumerable. Will check the new documents first. Does not load the entire enumerable.
332 333 334 335 336 337 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 332 def last(opts = {}) _added.values.try(:last) || _loaded.try(:values).try(:last) || _added[(ul = _unloaded.try(:last, opts)).try(:id)] || ul end |
#marshal_dump ⇒ Array<Object>
Provides the data needed to Marshal.dump an enumerable proxy.
370 371 372 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 370 def marshal_dump [_added, _loaded, _unloaded, @executed] end |
#marshal_load(data) ⇒ Array<Object>
Loads the data needed to Marshal.load an enumerable proxy.
382 383 384 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 382 def marshal_load(data) @_added, @_loaded, @_unloaded, @executed = data end |
#reset ⇒ false
Reset the enumerable back to its persisted state.
394 395 396 397 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 394 def reset _loaded.clear and _added.clear @executed = false end |
#reset_unloaded(criteria) ⇒ Object
Resets the underlying unloaded criteria object with a new one. Used my HABTM relations to keep the underlying array in sync.
408 409 410 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 408 def reset_unloaded(criteria) @_unloaded = criteria if _unloaded.is_a?(Criteria) end |
#respond_to?(name, include_private = false) ⇒ true, false
Does this enumerable respond to the provided method?
424 425 426 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 424 def respond_to?(name, include_private = false) [].respond_to?(name, include_private) || super end |
#size ⇒ Integer Also known as: length
Gets the total size of this enumerable. This is a combination of all the persisted and unpersisted documents.
437 438 439 440 441 442 443 444 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 437 def size count = (_unloaded ? _unloaded.count : _loaded.count) if count.zero? count + _added.count else count + _added.values.count { |d| d.new_record? } end end |
#to_json(options = {}) ⇒ String
Send #to_json to the entries.
458 459 460 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 458 def to_json( = {}) entries.to_json() end |
#uniq ⇒ Array<Document>
This operation loads all documents from the database.
Return all the unique documents in the enumerable.
486 487 488 |
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 486 def uniq entries.uniq end |