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


234
235
236
237
238
239
240
241
242
243
244
# File 'lib/mongoid/relations/targets/enumerable.rb', line 234

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)


456
457
458
# File 'lib/mongoid/relations/targets/enumerable.rb', line 456

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


61
62
63
64
# File 'lib/mongoid/relations/targets/enumerable.rb', line 61

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

#===(other) ⇒ true, false

Check equality of the enumerable against the provided object for case statements.

Examples:

Check case equality.

enumerable === Array

Parameters:

  • other (Object)

    The object to check.

Returns:

  • (true, false)

    If the objects are equal in a case.

Since:

  • 3.1.4


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

def ===(other)
  other.class == Class ? Array == 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.

Examples:

Is the enumerable _loaded?

enumerable._loaded?

Returns:

  • (true, false)

    If the enumerable has been _loaded.

Since:

  • 2.1.0


323
324
325
# File 'lib/mongoid/relations/targets/enumerable.rb', line 323

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


436
437
438
# File 'lib/mongoid/relations/targets/enumerable.rb', line 436

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


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

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


98
99
100
# File 'lib/mongoid/relations/targets/enumerable.rb', line 98

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


112
113
114
115
116
117
118
119
120
121
122
# File 'lib/mongoid/relations/targets/enumerable.rb', line 112

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


137
138
139
140
141
142
143
144
145
# File 'lib/mongoid/relations/targets/enumerable.rb', line 137

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.

If no block is passed then it returns an enumerator containing all docs.

Examples:

Iterate over the enumerable.

enumerable.each do |doc|
  puts doc
end

return an enumerator containing all the docs


a = enumerable.each

Returns:

  • (true)

    That the enumerable is now _loaded.

Since:

  • 2.1.0


172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/mongoid/relations/targets/enumerable.rb', line 172

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

Examples:

Is the enumerable empty?

enumerable.empty?

Returns:

  • (true, false)

    If the enumerable is empty.

Since:

  • 2.1.0


202
203
204
205
206
207
208
# File 'lib/mongoid/relations/targets/enumerable.rb', line 202

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


219
220
221
# File 'lib/mongoid/relations/targets/enumerable.rb', line 219

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


285
286
287
288
289
# File 'lib/mongoid/relations/targets/enumerable.rb', line 285

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


256
257
258
259
# File 'lib/mongoid/relations/targets/enumerable.rb', line 256

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


270
271
272
# File 'lib/mongoid/relations/targets/enumerable.rb', line 270

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


300
301
302
# File 'lib/mongoid/relations/targets/enumerable.rb', line 300

def last
  matching_document(:last)
end

#marshal_dumpArray<Object>

Provides the data needed to Marshal.dump an enumerable proxy.

Examples:

Dump the proxy.

Marshal.dump(proxy)

Returns:

  • (Array<Object>)

    The dumped data.

Since:

  • 3.0.15


335
336
337
# File 'lib/mongoid/relations/targets/enumerable.rb', line 335

def marshal_dump
  [ _added, _loaded, _unloaded ]
end

#marshal_load(data) ⇒ Array<Object>

Loads the data needed to Marshal.load an enumerable proxy.

Examples:

Load the proxy.

Marshal.load(proxy)

Returns:

  • (Array<Object>)

    The dumped data.

Since:

  • 3.0.15


347
348
349
# File 'lib/mongoid/relations/targets/enumerable.rb', line 347

def marshal_load(data)
  @_added, @_loaded, @_unloaded = data
end

#resetfalse

Reset the enumerable back to its persisted state.

Examples:

Reset the enumerable.

enumerable.reset

Returns:

  • (false)

    Always false.

Since:

  • 2.1.0


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

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.

Examples:

Reset the unloaded documents.

enumerable.reset_unloaded(criteria)

Parameters:

  • criteria (Criteria)

    The criteria to replace with.

Since:

  • 3.0.14


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

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?

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


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

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


402
403
404
405
406
407
408
409
# File 'lib/mongoid/relations/targets/enumerable.rb', line 402

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


422
423
424
# File 'lib/mongoid/relations/targets/enumerable.rb', line 422

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


450
451
452
# File 'lib/mongoid/relations/targets/enumerable.rb', line 450

def uniq
  entries.uniq
end