Class: Humanoid::Associations::HasMany

Inherits:
Object
  • Object
show all
Includes:
Proxy
Defined in:
lib/humanoid/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.



87
88
89
90
91
92
# File 'lib/humanoid/associations/has_many.rb', line 87

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.



98
99
100
101
102
103
104
105
# File 'lib/humanoid/associations/has_many.rb', line 98

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/humanoid/associations/has_many.rb', line 7

def association_name
  @association_name
end

#klassObject

Returns the value of attribute klass.



7
8
9
# File 'lib/humanoid/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



159
160
161
# File 'lib/humanoid/associations/has_many.rb', line 159

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

.macroObject

Returns the macro used to create the association.



164
165
166
# File 'lib/humanoid/associations/has_many.rb', line 164

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.



171
172
173
174
175
# File 'lib/humanoid/associations/has_many.rb', line 171

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/humanoid/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/humanoid/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/humanoid/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
# File 'lib/humanoid/associations/has_many.rb', line 55

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



70
71
72
73
# File 'lib/humanoid/associations/has_many.rb', line 70

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.



117
118
119
120
121
# File 'lib/humanoid/associations/has_many.rb', line 117

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.



133
134
135
136
137
# File 'lib/humanoid/associations/has_many.rb', line 133

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