Class: Mongoid::Relations::Targets::Enumerable

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/mongoid/relations/targets/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

Instance Method Summary collapse

Constructor Details

#initialize(target) ⇒ Enumerable

Initialize the new enumerable either with a criteria or an array.

Examples:

Initialize the enumerable with a criteria.

Enumberable.new(Post.where(:person_id => id))

Initialize the enumerable with an array.

Enumerable.new([ post ])

Parameters:

Since:

  • 2.1.0



209
210
211
212
213
214
215
216
217
218
219
# File 'lib/mongoid/relations/targets/enumerable.rb', line 209

def initialize(target)
  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
      _target
    end
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object (private)



394
395
396
# File 'lib/mongoid/relations/targets/enumerable.rb', line 394

def method_missing(name, *args, &block)
  entries.send(name, *args, &block)
end

Instance Attribute Details

#_addedObject

The three main instance variables are collections of documents.



17
18
19
# File 'lib/mongoid/relations/targets/enumerable.rb', line 17

def _added
  @_added
end

#_added Documents that have been appended.(Documentsthathavebeenappended.) ⇒ Object

The three main instance variables are collections of documents.



17
# File 'lib/mongoid/relations/targets/enumerable.rb', line 17

attr_accessor :_added, :_loaded, :_unloaded

#_loadedObject

The three main instance variables are collections of documents.



17
18
19
# File 'lib/mongoid/relations/targets/enumerable.rb', line 17

def _loaded
  @_loaded
end

#_loaded Persisted documents that have been _loaded.(Persisteddocumentsthathavebeen_loaded.) ⇒ Object

The three main instance variables are collections of documents.



17
# File 'lib/mongoid/relations/targets/enumerable.rb', line 17

attr_accessor :_added, :_loaded, :_unloaded

#_unloadedObject

The three main instance variables are collections of documents.



17
18
19
# File 'lib/mongoid/relations/targets/enumerable.rb', line 17

def _unloaded
  @_unloaded
end

#_unloaded A criteria representing persisted docs.(Acriteriarepresentingpersisteddocs.) ⇒ Object

The three main instance variables are collections of documents.



17
# File 'lib/mongoid/relations/targets/enumerable.rb', line 17

attr_accessor :_added, :_loaded, :_unloaded

Instance Method Details

#<<(document) ⇒ Document Also known as: push

Append a document to the enumerable.

Examples:

Append the document.

enumerable << document

Parameters:

  • document (Document)

    The document to append.

Returns:

Since:

  • 2.1.0



46
47
48
49
# File 'lib/mongoid/relations/targets/enumerable.rb', line 46

def <<(document)
  _added[document.id] = document
  self
end

#==(other) ⇒ true, false

Check if the enumerable is equal to the other object.

Examples:

Check equality.

enumerable == []

Parameters:

Returns:

  • (true, false)

    If the objects are equal.

Since:

  • 2.1.0



31
32
33
34
# File 'lib/mongoid/relations/targets/enumerable.rb', line 31

def ==(other)
  return false unless other.respond_to?(:entries)
  entries == other.entries
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.

Examples:

Is the enumerable _loaded?

enumerable._loaded?

Returns:

  • (true, false)

    If the enumerable has been _loaded.

Since:

  • 2.1.0



298
299
300
# File 'lib/mongoid/relations/targets/enumerable.rb', line 298

def _loaded?
  !!@executed
end

#as_json(options = {}) ⇒ Hash

Send #as_json to the entries, without encoding.

Examples:

Get the enumerable as json.

enumerable.as_json

Parameters:

  • options (Hash) (defaults to: {})

    Optional parameters.

Returns:

  • (Hash)

    The entries all _loaded as a hash.

Since:

  • 2.2.0



374
375
376
# File 'lib/mongoid/relations/targets/enumerable.rb', line 374

def as_json(options = {})
  entries.as_json(options)
end

#clearArray<Document>

Clears out all the documents in this enumerable. If passed a block it will yield to each document that is in memory.

Examples:

Clear out the enumerable.

enumerable.clear

Clear out the enumerable with a block.

enumerable.clear do |doc|
  doc.unbind
end

Returns:

  • (Array<Document>)

    The cleared out _added docs.

Since:

  • 2.1.0



66
67
68
69
70
71
# File 'lib/mongoid/relations/targets/enumerable.rb', line 66

def clear
  if block_given?
    in_memory { |doc| yield(doc) }
  end
  _loaded.clear and _added.clear
end

#cloneArray<Document>

Note:

This loads all documents into memory.

Clones each document in the enumerable.

Examples:

Clone the enumerable.

enumerable.clone

Returns:

  • (Array<Document>)

    An array clone of the enumerable.

Since:

  • 2.1.6



83
84
85
# File 'lib/mongoid/relations/targets/enumerable.rb', line 83

def clone
  collect { |doc| doc.clone }
end

#delete(document) {|doc| ... } ⇒ Document

Delete the supplied document from the enumerable.

Examples:

Delete the document.

enumerable.delete(document)

Parameters:

  • document (Document)

    The document to delete.

Yields:

  • (doc)

Returns:

Since:

  • 2.1.0



97
98
99
100
101
102
103
104
105
106
107
# File 'lib/mongoid/relations/targets/enumerable.rb', line 97

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>

Note:

This operation loads all documents from the database.

Deletes every document in the enumerable for where the block returns true.

Examples:

Delete all matching documents.

enumerable.delete_if do |doc|
  dod.id == id
end

Returns:

  • (Array<Document>)

    The remaining docs.

Since:

  • 2.1.0



122
123
124
125
126
127
128
129
130
# File 'lib/mongoid/relations/targets/enumerable.rb', line 122

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

#eachtrue

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.

Examples:

Iterate over the enumerable.

enumerable.each do |doc|
  puts doc
end

Returns:

  • (true)

    That the enumerable is now _loaded.

Since:

  • 2.1.0



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/mongoid/relations/targets/enumerable.rb', line 150

def each
  if _loaded?
    _loaded.each_pair do |id, doc|
      yield(doc)
    end
  else
    _unloaded.each do |doc|
      document = _added.delete(doc.id) || _loaded.delete(doc.id) || doc
      yield(document)
      _loaded[document.id] = 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.

Examples:

Is the enumerable empty?

enumerable.empty?

Returns:

  • (true, false)

    If the enumerable is empty.

Since:

  • 2.1.0



177
178
179
180
181
182
183
# File 'lib/mongoid/relations/targets/enumerable.rb', line 177

def empty?
  if _loaded?
    in_memory.count == 0
  else
    _unloaded.count + _added.count == 0
  end
end

#firstDocument

Get the first document in the enumerable. Will check the persisted documents first. Does not load the entire enumerable.

Examples:

Get the first document.

enumerable.first

Returns:

  • (Document)

    The first document found.

Since:

  • 2.1.0



194
195
196
# File 'lib/mongoid/relations/targets/enumerable.rb', line 194

def first
  matching_document(:first)
end

#in_memoryArray<Document>

Note:

When passed a block it yields to each document.

Return all the documents in the enumerable that have been _loaded or _added.

Examples:

Get the in memory docs.

enumerable.in_memory

Returns:

  • (Array<Document>)

    The in memory docs.

Since:

  • 2.1.0



260
261
262
263
264
# File 'lib/mongoid/relations/targets/enumerable.rb', line 260

def in_memory
  docs = (_loaded.values + _added.values)
  docs.each { |doc| yield(doc) } if block_given?
  docs
end

#include?(doc) ⇒ true, false

Does the target include the provided document?

Examples:

Does the target include the document?

enumerable.include?(document)

Parameters:

  • doc (Document)

    The document to check.

Returns:

  • (true, false)

    If the document is in the target.

Since:

  • 3.0.0



231
232
233
234
# File 'lib/mongoid/relations/targets/enumerable.rb', line 231

def include?(doc)
  return super unless _unloaded
  _unloaded.where(_id: doc.id).exists? || _added.has_key?(doc.id)
end

#inspectString

Inspection will just inspect the entries for nice array-style printing.

Examples:

Inspect the enumerable.

enumerable.inspect

Returns:

  • (String)

    The inspected enum.

Since:

  • 2.1.0



245
246
247
# File 'lib/mongoid/relations/targets/enumerable.rb', line 245

def inspect
  entries.inspect
end

#lastDocument

Get the last document in the enumerable. Will check the new documents first. Does not load the entire enumerable.

Examples:

Get the last document.

enumerable.last

Returns:

  • (Document)

    The last document found.

Since:

  • 2.1.0



275
276
277
# File 'lib/mongoid/relations/targets/enumerable.rb', line 275

def last
  matching_document(:last)
end

#resetfalse

Reset the enumerable back to it’s persisted state.

Examples:

Reset the enumerable.

enumerable.reset

Returns:

  • (false)

    Always false.

Since:

  • 2.1.0



310
311
312
313
# File 'lib/mongoid/relations/targets/enumerable.rb', line 310

def reset
  _loaded.clear and _added.clear
  @executed = false
end

#respond_to?(name, include_private = false) ⇒ true, false

Does this enumerable respond to the provided method?

Examples:

Does the enumerable respond to the method?

enumerable.respond_to?(:sum)

Parameters:

  • name (String, Symbol)

    The name of the method.

  • include_private (true, false) (defaults to: false)

    Whether to include private methods.

Returns:

  • (true, false)

    Whether the enumerable responds.

Since:

  • 2.1.0



327
328
329
# File 'lib/mongoid/relations/targets/enumerable.rb', line 327

def respond_to?(name, include_private = false)
  [].respond_to?(name, include_private) || super
end

#sizeInteger Also known as: length

Gets the total size of this enumerable. This is a combination of all the persisted and unpersisted documents.

Examples:

Get the size.

enumerable.size

Returns:

  • (Integer)

    The size of the enumerable.

Since:

  • 2.1.0



340
341
342
343
344
345
346
347
# File 'lib/mongoid/relations/targets/enumerable.rb', line 340

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.

Examples:

Get the enumerable as json.

enumerable.to_json

Parameters:

  • options (Hash) (defaults to: {})

    Optional parameters.

Returns:

  • (String)

    The entries all _loaded as a string.

Since:

  • 2.2.0



360
361
362
# File 'lib/mongoid/relations/targets/enumerable.rb', line 360

def to_json(options = {})
  entries.to_json(options)
end

#uniqArray<Document>

Note:

This operation loads all documents from the database.

Return all the unique documents in the enumerable.

Examples:

Get all the unique documents.

enumerable.uniq

Returns:

  • (Array<Document>)

    The unique documents.

Since:

  • 2.1.0



388
389
390
# File 'lib/mongoid/relations/targets/enumerable.rb', line 388

def uniq
  entries.uniq
end