Class: Mongoid::Associations::EmbedsMany

Inherits:
Proxy show all
Defined in:
lib/mongoid/associations/embeds_many.rb

Overview

Represents embedding many documents within a parent document, which will be an array as the underlying storage mechanism.

Instance Attribute Summary collapse

Attributes inherited from Proxy

#options, #target

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Proxy

#extends

Constructor Details

#initialize(parent, options, target_array = nil) ⇒ EmbedsMany

Creates the new association by finding the attributes in the parent document with its name, and instantiating a new document for each one found. These will then be put in an internal array.

This then delegated all methods to the array class since this is essentially a proxy to an array itself.

Options:

parent: The parent document to the association. options: The association options.



130
131
132
133
134
135
136
137
138
139
# File 'lib/mongoid/associations/embeds_many.rb', line 130

def initialize(parent, options, target_array = nil)
  @parent, @association_name = parent, options.name
  @klass, @options = options.klass, options
  if target_array
    build_children_from_target_array(target_array)
  else
    build_children_from_attributes(parent.raw_attributes[@association_name])
  end
  extends(options)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

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

If the target array does not respond to the supplied method then try to find a named scope or criteria on the class and send the call there.

If the method exists on the array, use the default proxy behavior.



147
148
149
150
151
152
153
154
# File 'lib/mongoid/associations/embeds_many.rb', line 147

def method_missing(name, *args, &block)
  unless @target.respond_to?(name)
    object = @klass.send(name, *args)
    object.documents = @target
    return object
  end
  super
end

Instance Attribute Details

#association_nameObject

Returns the value of attribute association_name.



8
9
10
# File 'lib/mongoid/associations/embeds_many.rb', line 8

def association_name
  @association_name
end

#klassObject

Returns the value of attribute klass.



8
9
10
# File 'lib/mongoid/associations/embeds_many.rb', line 8

def klass
  @klass
end

Class Method Details

.instantiate(document, options, target_array = nil) ⇒ Object

Preferred method of creating a new EmbedsMany association. It will delegate to new.

Options:

document: The parent Document options: The association options



230
231
232
# File 'lib/mongoid/associations/embeds_many.rb', line 230

def instantiate(document, options, target_array = nil)
  new(document, options, target_array)
end

.macroObject

Returns the macro used to create the association.



235
236
237
# File 'lib/mongoid/associations/embeds_many.rb', line 235

def macro
  :embeds_many
end

.update(children, parent, options) ⇒ Object

Perform an update of the relationship of the parent and child. This is initialized by setting the has_many to the supplied Enumerable and setting up the parentization.



242
243
244
245
246
247
248
249
250
# File 'lib/mongoid/associations/embeds_many.rb', line 242

def update(children, parent, options)
  parent.raw_attributes.delete(options.name)
  children.assimilate(parent, options)
  if children && children.first.is_a?(Mongoid::Document)
    instantiate(parent, options, children)
  else
    instantiate(parent, options)
  end
end

Instance Method Details

#<<(*documents) ⇒ Object Also known as: concat, push

Appends the object to the Array, setting its parent in the process.



12
13
14
15
16
17
18
19
# File 'lib/mongoid/associations/embeds_many.rb', line 12

def <<(*documents)
  documents.flatten.each do |doc|
    doc.parentize(@parent, @association_name)
    @target << doc
    doc._index = @target.size - 1
    doc.notify
  end
end

#build(attrs = {}, type = nil) ⇒ Object

Builds a new Document and adds it to the association collection. The document created will be of the same class as the others in the association, and the attributes will be passed into the constructor.

Returns:

The newly created Document.



31
32
33
34
35
36
37
38
# File 'lib/mongoid/associations/embeds_many.rb', line 31

def build(attrs = {}, type = nil)
  document = type ? type.instantiate : @klass.instantiate
  document.parentize(@parent, @association_name)
  document.write_attributes(attrs)
  @target << document
  document._index = @target.size - 1
  document
end

#clearObject

Clears the association, and notifies the parents of the removal.



41
42
43
44
45
46
47
# File 'lib/mongoid/associations/embeds_many.rb', line 41

def clear
  unless @target.empty?
    document = @target.first
    document.notify_observers(document, true)
    @target.clear
  end
end

#create(attrs = {}, type = nil) ⇒ Object

Creates a new Document and adds it to the association collection. The document created will be of the same class as the others in the association, and the attributes will be passed into the constructor and the new object will then be saved.

Returns:

The newly created Document.



57
58
59
60
# File 'lib/mongoid/associations/embeds_many.rb', line 57

def create(attrs = {}, type = nil)
  document = build(attrs, type)
  document.save; document
end

#create!(attrs = {}, type = nil) ⇒ Object

Creates a new Document and adds it to the association collection. The document created will be of the same class as the others in the association, and the attributes will be passed into the constructor and the new object will then be saved. If validation fails an error will get raised.

Returns:

The newly created Document.



71
72
73
74
75
76
# File 'lib/mongoid/associations/embeds_many.rb', line 71

def create!(attrs = {}, type = nil)
  document = create(attrs, type)
  errors = document.errors
  raise Errors::Validations.new(errors) unless errors.empty?
  document
end

#delete_all(conditions = {}) ⇒ Object

Delete all the documents in the association without running callbacks.

Example:

addresses.delete_all

Returns:

The number of documents deleted.



87
88
89
# File 'lib/mongoid/associations/embeds_many.rb', line 87

def delete_all(conditions = {})
  remove(:delete, conditions)
end

#destroy_all(conditions = {}) ⇒ Object

Delete all the documents in the association and run destroy callbacks.

Example:

addresses.destroy_all

Returns:

The number of documents destroyed.



100
101
102
# File 'lib/mongoid/associations/embeds_many.rb', line 100

def destroy_all(conditions = {})
  remove(:destroy, conditions)
end

#find(param) ⇒ Object

Finds a document in this association.

If :all is passed, returns all the documents

If an id is passed, will return the document for that id.

Returns:

Array or single Document.



113
114
115
116
# File 'lib/mongoid/associations/embeds_many.rb', line 113

def find(param)
  return @target if param == :all
  return detect { |document| document.id == param }
end

#nested_build(attributes) ⇒ Object

Used for setting associations via a nested attributes setter from the parent Document.

Options:

attributes: A Hash of integer keys and Hash values.

Returns:

The newly build target Document.



166
167
168
169
170
# File 'lib/mongoid/associations/embeds_many.rb', line 166

def nested_build(attributes)
  attributes.values.each do |attrs|
    build(attrs)
  end
end

#paginate(options) ⇒ Object

Paginate the association. Will create a new criteria, set the documents on it and execute in an enumerable context.

Options:

options: A Hash of pagination options.

Returns:

A WillPaginate::Collection.



182
183
184
185
186
# File 'lib/mongoid/associations/embeds_many.rb', line 182

def paginate(options)
  criteria = Mongoid::Criteria.translate(@klass, options)
  criteria.documents = @target
  criteria.paginate(options)
end