Class: Mongoid::Association::Referenced::HasMany::Enumerable
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
Forwardable
|
|
Instance Chain:
self,
Enumerable
|
|
Inherits: | Object |
Defined in: | lib/mongoid/association/referenced/has_many/enumerable.rb |
Overview
This class is the wrapper for all referenced 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.
Class Method Summary
-
.new(target, base = nil, association = nil) ⇒ Enumerable
constructor
Initialize the new enumerable either with a criteria or an array.
Instance Attribute Summary
-
#_added
rw
The three main instance variables are collections of documents.
-
#_added Documents that have been appended.(Documents that have been appended.)
rw
The three main instance variables are collections of documents.
-
#_loaded
rw
The three main instance variables are collections of documents.
-
#_loaded Persisted documents that have been _loaded.(Persisted documents that have been _loaded.)
rw
The three main instance variables are collections of documents.
-
#_loaded? ⇒ true | false
rw
Has the enumerable been _loaded? This will be true if the criteria has been executed or we manually load the entire thing.
-
#_unloaded
rw
The three main instance variables are collections of documents.
-
#_unloaded A criteria representing persisted docs.(A criteria representing persisted docs.)
rw
The three main instance variables are collections of documents.
-
#empty? ⇒ true | false
readonly
Is the enumerable empty? Will determine if the count is zero based on whether or not it is _loaded.
Instance Method Summary
-
#<<(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.
-
#any?(*args) ⇒ true | false
Returns whether the association has any documents, optionally subject to the provided filters.
-
#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.
-
#first(limit = nil) ⇒ 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?
-
#inspect ⇒ String
Inspection will just inspect the entries for nice array-style printing.
-
#last(limit = nil) ⇒ Document
Get the last document in the enumerable.
-
#length
Alias for #size.
-
#load_all! ⇒ true
Loads all the documents in the enumerable from the database.
-
#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.
-
#push(document)
Alias for #<<.
-
#reset ⇒ false
Reset the enumerable back to its persisted state.
-
#reset_unloaded(criteria)
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.
- #set_base(document) private
- #unloaded_documents private
-
#unsatisfiable_criteria?(selector) ⇒ true | false
private
Checks whether conditions in the given hash are known to be unsatisfiable, i.e. querying with this hash will always return no documents.
Constructor Details
.new(target, base = nil, association = nil) ⇒ Enumerable
Initialize the new enumerable either with a criteria or an array.
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 262
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
Instance Attribute Details
#_added (rw)
The three main instance variables are collections of documents.
#_added Documents that have been appended.(Documents that have been appended.) (rw)
The three main instance variables are collections of documents.
#_loaded (rw)
The three main instance variables are collections of documents.
#_loaded Persisted documents that have been _loaded.(Persisted documents that have been _loaded.) (rw)
The three main instance variables are collections of documents.
#_loaded? ⇒ true
| false
(rw)
Has the enumerable been _loaded? This will be true if the criteria has been executed or we manually load the entire thing.
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 353
def _loaded? !!@executed end
#_unloaded (rw)
The three main instance variables are collections of documents.
#_unloaded A criteria representing persisted docs.(A criteria representing persisted docs.) (rw)
The three main instance variables are collections of documents.
#empty? ⇒ true
| false
(readonly)
Is the enumerable empty? Will determine if the count is zero based on whether or not it is _loaded.
Instance Method Details
#<<(document) ⇒ Document Also known as: #push
Append a document to the enumerable.
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 60
def <<(document) _added[document._id] = document self end
#==(other) ⇒ true
| false
Check if the enumerable is equal to the other object.
# 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.
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 47
def ===(other) return false unless other.respond_to?(:entries) entries === other.entries end
#any?(*args) ⇒ true
| false
Returns whether the association has any documents, optionally subject to the provided filters.
This method returns true if the association has any persisted documents and if it has any not yet persisted documents.
If the association is already loaded, this method inspects the loaded documents and does not query the database. If the association is not loaded, the argument-less and block-less version does not load the association; the other versions (that delegate to Enumerable
) may or may not load the association completely depending on whether it is iterated to completion.
This method can take a parameter and a block. The behavior with either the parameter or the block is delegated to the standard library Enumerable
module.
Note that when Enumerable’s any? method is invoked with both a block and a pattern, it only uses the pattern.
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 225
def any?(*args) return super if args.any? || block_given? !empty? end
#as_json(options = {}) ⇒ Hash
Send #as_json to the entries, without encoding.
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 452
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.
#clone ⇒ Array<Document>
This loads all documents into memory.
Clones each document in the enumerable.
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 94
def clone collect { |doc| doc.clone } end
#delete(document) {|doc| ... } ⇒ Document
Delete the supplied document from the enumerable.
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 106
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.
#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.
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 162
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
#first(limit = nil) ⇒ 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 #take instead. Be aware that #take won’t guarantee order.
Get the first document in the enumerable. Will check the persisted documents first. Does not load the entire enumerable.
#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.
#include?(doc) ⇒ true
| false
Does the target include the provided document?
#inspect ⇒ String
Inspection will just inspect the entries for nice array-style printing.
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 296
def inspect entries.inspect end
#last(limit = nil) ⇒ 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 #take instead. Be aware that #take won’t guarantee order.
Get the last document in the enumerable. Will check the new documents first. Does not load the entire enumerable.
#length
Alias for #size.
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 430
alias :length :size
#load_all! ⇒ true
Loads all the documents in the enumerable from the database.
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 344
alias :load_all! :entries
#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.
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 373
def marshal_load(data) @_added, @_loaded, @_unloaded, @executed = data end
#push(document)
Alias for #<<.
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 65
alias :push :<<
#reset ⇒ false
Reset the enumerable back to its persisted state.
#reset_unloaded(criteria)
Resets the underlying unloaded criteria object with a new one. Used my HABTM associations to keep the underlying array in sync.
#respond_to?(name, include_private = false) ⇒ true
| false
Does this enumerable respond to the provided method?
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 410
def respond_to?(name, include_private = false) [].respond_to?(name, include_private) || super end
#set_base(document) (private)
[ GitHub ]# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 470
def set_base(document) if @_association.is_a?(Referenced::HasMany) document.set_relation(@_association.inverse, @_base) if @_association end 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.
#to_json(options = {}) ⇒ String
Send #to_json to the entries.
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 440
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.
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 464
def uniq entries.uniq end
#unloaded_documents (private)
[ GitHub ]# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 480
def unloaded_documents if unsatisfiable_criteria?(_unloaded.selector) [] else _unloaded end end
#unsatisfiable_criteria?(selector) ⇒ true
| false
(private)
Checks whether conditions in the given hash are known to be unsatisfiable, i.e. querying with this hash will always return no documents.
This method only handles condition shapes that ::Mongoid
itself uses when it builds association queries. Return value true indicates the condition always produces an empty document set. Note however that return value false is not a guarantee that the condition won’t produce an empty document set.
# File 'lib/mongoid/association/referenced/has_many/enumerable.rb', line 513
def unsatisfiable_criteria?(selector) unsatisfiable_criteria = { '_id' => { '$in' => [] } } return true if selector == unsatisfiable_criteria return false unless selector.length == 1 && selector.keys == %w[$and] value = selector.values.first value.is_a?(Array) && value.any? do |sub_value| sub_value.is_a?(Hash) && unsatisfiable_criteria?(sub_value) end end