class Mongoid::Relations::Embedded::Many

This class handles the behaviour for a document that embeds many other documents within in it as an array.

Public Class Methods

new(base, target, metadata) click to toggle source

Instantiate a new embeds_many relation.

@example Create the new relation.

Many.new(person, addresses, metadata)

@param [ Document ] base The document this relation hangs off of. @param [ Array<Document> ] target The child documents of the relation. @param [ Metadata ] metadata The relation's metadata

@return [ Many ] The proxy.

# File lib/mongoid/relations/embedded/many.rb, line 252
def initialize(base, target, metadata)
  init(base, target, metadata) do
    target.each_with_index do |doc, index|
      integrate(doc)
      doc._index = index
    end
    @_unscoped = target.dup
    @target = scope(target)
  end
end

Public Instance Methods

<<(*args) click to toggle source

Appends a document or array of documents to the relation. Will set the parent and update the index in the process.

@example Append a document.

person.addresses << address

@example Push a document.

person.addresses.push(address)

@param [ Document, Array<Document> ] *args Any number of documents.

# File lib/mongoid/relations/embedded/many.rb, line 22
def <<(*args)
  docs = args.flatten
  return concat(docs) if docs.size > 1
  if doc = docs.first
    append(doc)
    doc.save if persistable? && !_assigning?
  end
  self
end
Also aliased as: push
as_document() click to toggle source

Get this relation as as its representation in the database.

@example Convert the relation to an attributes hash.

person.addresses.as_document

@return [ Array<Hash> ] The relation as stored in the db.

@since 2.0.0.rc.1

# File lib/mongoid/relations/embedded/many.rb, line 41
def as_document
  attributes = []
  _unscoped.each do |doc|
    attributes.push(doc.as_document)
  end
  attributes
end
build(attributes = {}, options = {}, type = nil) { |doc| ... } click to toggle source

Builds a new document in the relation and appends it to the target. Takes an optional type if you want to specify a subclass.

@example Build a new document on the relation.

person.people.build(:name => "Bozo")

@overload build(attributes = {}, options = {}, type = nil)

@param [ Hash ] attributes The attributes to build the document with.
@param [ Hash ] options The scoped assignment options.
@param [ Class ] type Optional class to build the document with.

@overload build(attributes = {}, type = nil)

@param [ Hash ] attributes The attributes to build the document with.
@param [ Class ] type Optional class to build the document with.

@return [ Document ] The new document.

# File lib/mongoid/relations/embedded/many.rb, line 81
def build(attributes = {}, options = {}, type = nil)
  if options.is_a?(Class)
    options, type = {}, options
  end
  doc = Factory.build(type || metadata.klass, attributes, options)
  append(doc)
  doc.apply_post_processed_defaults
  yield(doc) if block_given?
  doc.run_callbacks(:build) { doc }
  doc
end
Also aliased as: new
clear() click to toggle source

Clear the relation. Will delete the documents from the db if they are already persisted.

@example Clear the relation.

person.addresses.clear

@return [ Many ] The empty relation.

# File lib/mongoid/relations/embedded/many.rb, line 101
def clear
  batch_clear(target.dup)
  self
end
concat(docs) click to toggle source

Appends an array of documents to the relation. Performs a batch insert of the documents instead of persisting one at a time.

@example Concat with other documents.

person.addresses.concat([ address_one, address_two ])

@param [ Array<Document> ] docs The docs to add.

@return [ Array<Document> ] The documents.

@since 2.4.0

# File lib/mongoid/relations/embedded/many.rb, line 60
def concat(docs)
  batch_insert(docs) unless docs.empty?
  self
end
count() click to toggle source

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.

@example Get the count of persisted documents.

person.addresses.count

@return [ Integer ] The total number of persisted embedded docs, as

flagged by the #persisted? method.
# File lib/mongoid/relations/embedded/many.rb, line 116
def count
  target.select { |doc| doc.persisted? }.size
end
delete(document) click to toggle source

Delete the supplied document from the target. This method is proxied in order to reindex the array after the operation occurs.

@example Delete the document from the relation.

person.addresses.delete(address)

@param [ Document ] document The document to be deleted.

@return [ Document, nil ] The deleted document or nil if nothing deleted.

@since 2.0.0.rc.1

# File lib/mongoid/relations/embedded/many.rb, line 131
def delete(document)
  execute_callback :before_remove, document
  doc = target.delete_one(document)
  if doc && !_binding?
    _unscoped.delete_one(doc) unless doc.paranoid?
    if _assigning?
      if doc.paranoid?
        doc.destroy(suppress: true)
      else
        base.add_atomic_pull(doc)
      end
    else
      doc.delete(suppress: true)
      unbind_one(doc)
    end
  end
  reindex
  execute_callback :after_remove, document
  doc
end
delete_all(conditions = {}) click to toggle source

Delete all the documents in the association without running callbacks.

@example Delete all documents from the relation.

person.addresses.delete_all

@example Conditionally delete documents from the relation.

person.addresses.delete_all({ :street => "Bond" })

@param [ Hash ] conditions Conditions on which documents to delete.

@return [ Integer ] The number of documents deleted.

# File lib/mongoid/relations/embedded/many.rb, line 175
def delete_all(conditions = {})
  remove_all(conditions, :delete)
end
delete_if() { |doc| ... } click to toggle source

Delete all the documents for which the provided block returns true.

@example Delete the matching documents.

person.addresses.delete_if do |doc|
  doc.state = "GA"
end

@return [ Many, Enumerator ] The relation or an enumerator if no

block was provided.

@since 3.1.0

# File lib/mongoid/relations/embedded/many.rb, line 190
def delete_if
  if block_given?
    target.each do |doc|
      delete(doc) if yield(doc)
    end
    self
  else
    super
  end
end
deleted() click to toggle source

For use only with Mongoid::Paranoia - will be removed in 4.0.

@example Get the deleted documents from the relation.

person.paranoid_phones.deleted

@return [ Criteria ] The deleted documents.

@since 3.0.10

# File lib/mongoid/relations/embedded/many.rb, line 160
def deleted
  unscoped.deleted
end
destroy_all(conditions = {}) click to toggle source

Destroy all the documents in the association whilst running callbacks.

@example Destroy all documents from the relation.

person.addresses.destroy_all

@example Conditionally destroy documents from the relation.

person.addresses.destroy_all({ :street => "Bond" })

@param [ Hash ] conditions Conditions on which documents to destroy.

@return [ Integer ] The number of documents destroyed.

# File lib/mongoid/relations/embedded/many.rb, line 212
def destroy_all(conditions = {})
  remove_all(conditions, :destroy)
end
exists?() click to toggle source

Determine if any documents in this relation exist in the database.

@example Are there persisted documents?

person.posts.exists?

@return [ true, false ] True is persisted documents exist, false if not.

# File lib/mongoid/relations/embedded/many.rb, line 222
def exists?
  count > 0
end
find(*args) click to toggle source

Finds a document in this association through several different methods.

@example Find a document by its id.

person.addresses.find(Moped::BSON::ObjectId.new)

@example Find documents for multiple ids.

person.addresses.find([ Moped::BSON::ObjectId.new, Moped::BSON::ObjectId.new ])

@param [ Array<Object> ] args Various arguments.

@return [ Array<Document>, Document ] A single or multiple documents.

# File lib/mongoid/relations/embedded/many.rb, line 238
def find(*args)
  criteria.find(*args)
end
in_memory() click to toggle source

Get all the documents in the relation that are loaded into memory.

@example Get the in memory documents.

relation.in_memory

@return [ Array<Document> ] The documents in memory.

@since 2.1.0

# File lib/mongoid/relations/embedded/many.rb, line 271
def in_memory
  target
end
new(attributes = {}, options = {}, type = nil) click to toggle source
Alias for: build
pop(count = nil) click to toggle source

Pop documents off the relation. This can be a single document or multiples, and will automatically persist the changes.

@example Pop a single document.

relation.pop

@example Pop multiple documents.

relation.pop(3)

@param [ Integer ] count The number of documents to pop, or 1 if not

provided.

@return [ Document, Array<Document> ] The popped document(s).

@since 3.0.0

# File lib/mongoid/relations/embedded/many.rb, line 290
def pop(count = nil)
  if count
    if docs = target[target.size - count, target.size]
      docs.each { |doc| delete(doc) }
    end
  else
    delete(target[-1])
  end
end
push(*args) click to toggle source
Alias for: <<
substitute(docs) click to toggle source

Substitutes the supplied target documents for the existing documents in the relation.

@example Substitute the relation's target.

person.addresses.substitute([ address ])

@param [ Array<Document> ] docs The replacement docs.

@return [ Many ] The proxied relation.

@since 2.0.0.rc.1

# File lib/mongoid/relations/embedded/many.rb, line 311
def substitute(docs)
  batch_replace(docs)
  self
end
unscoped() click to toggle source

Return the relation with all previous scoping removed. This is the exact representation of the docs in the database.

@example Get the unscoped documents.

person.addresses.unscoped

@return [ Criteria ] The unscoped relation.

@since 2.4.0

# File lib/mongoid/relations/embedded/many.rb, line 325
def unscoped
  criterion = klass.unscoped
  criterion.embedded = true
  criterion.documents = _unscoped.delete_if(&:marked_for_destruction?)
  criterion
end