Class: Mongoid::Associations::HasMany

Inherits:
Object
  • Object
show all
Includes:
Proxy
Defined in:
lib/mongoid/associations/has_many.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Proxy

included

Constructor Details

#initialize(parent, options) ⇒ HasMany

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.



89
90
91
92
93
94
# File 'lib/mongoid/associations/has_many.rb', line 89

def initialize(parent, options)
  @parent, @association_name = parent, options.name
  @klass, @options = options.klass, options
  initialize_each(parent.raw_attributes[@association_name])
  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.



100
101
102
103
104
105
106
107
# File 'lib/mongoid/associations/has_many.rb', line 100

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.



7
8
9
# File 'lib/mongoid/associations/has_many.rb', line 7

def association_name
  @association_name
end

#klassObject

Returns the value of attribute klass.



7
8
9
# File 'lib/mongoid/associations/has_many.rb', line 7

def klass
  @klass
end

Class Method Details

.instantiate(document, options) ⇒ Object

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

Options:

document: The parent Document options: The association options



161
162
163
# File 'lib/mongoid/associations/has_many.rb', line 161

def instantiate(document, options)
  new(document, options)
end

.macroObject

Returns the macro used to create the association.



166
167
168
# File 'lib/mongoid/associations/has_many.rb', line 166

def macro
  :has_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.



173
174
175
176
177
# File 'lib/mongoid/associations/has_many.rb', line 173

def update(children, parent, options)
  parent.remove_attribute(options.name)
  children.assimilate(parent, options)
  instantiate(parent, options)
end

Instance Method Details

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

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



11
12
13
14
15
16
17
# File 'lib/mongoid/associations/has_many.rb', line 11

def <<(*objects)
  objects.flatten.each do |object|
    object.parentize(@parent, @association_name)
    @target << object
    object.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.



39
40
41
42
43
44
45
# File 'lib/mongoid/associations/has_many.rb', line 39

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

#clearObject

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



23
24
25
26
27
28
29
30
# File 'lib/mongoid/associations/has_many.rb', line 23

def clear
  unless @target.empty?
    object = @target.first
    object.changed(true)
    object.notify_observers(object, 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:

Rhe newly created Document.



55
56
57
58
59
60
61
# File 'lib/mongoid/associations/has_many.rb', line 55

def create(attrs = {}, type = nil)
  object = build(attrs, type)
  object.run_callbacks(:before_create)
  object.save
  object.run_callbacks(:after_create)
  object
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.



72
73
74
75
# File 'lib/mongoid/associations/has_many.rb', line 72

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.



119
120
121
122
123
# File 'lib/mongoid/associations/has_many.rb', line 119

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.



135
136
137
138
139
# File 'lib/mongoid/associations/has_many.rb', line 135

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