Module: Dynamoid::Associations::ManyAssociation

Includes:
Association, Enumerable
Included in:
HasAndBelongsToMany, HasMany
Defined in:
lib/dynamoid/associations/many_association.rb

Instance Attribute Summary collapse

Attributes included from Association

#loaded, #name, #options, #source

Instance Method Summary collapse

Methods included from Association

#declaration_field_name, #declaration_field_type, #disassociate_source, #loaded?, #reset, #target

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object

Delegate methods we don't find directly to the records array.

Since:

  • 0.2.0


214
215
216
217
218
219
220
# File 'lib/dynamoid/associations/many_association.rb', line 214

def method_missing(method, *args)
  if records.respond_to?(method)
    records.send(method, *args)
  else
    super
  end
end

Instance Attribute Details

#queryObject

Returns the value of attribute query


8
9
10
# File 'lib/dynamoid/associations/many_association.rb', line 8

def query
  @query
end

Instance Method Details

#<<(object) ⇒ Dynamoid::Document

Add an object or array of objects to an association.

tag.posts << post
tag.posts << [post1, post2, post3]

This preserves the current records in the association (if any) and adds the object to the target association if it is detected to exist.

It saves both models immediately - the source model and the target one so any not saved changes will be saved as well.

Parameters:

  • object (Dynamoid::Document|Array)

    model (or array of models) to add to the association

Returns:

Since:

  • 0.2.0


89
90
91
92
93
94
95
96
97
# File 'lib/dynamoid/associations/many_association.rb', line 89

def <<(object)
  associate(Array(object).collect(&:hash_key))

  if target_association
    Array(object).each { |obj| obj.send(target_association).associate(source.hash_key) }
  end

  object
end

#==(other) ⇒ Boolean

Is this array equal to the association's records?

Returns:

  • (Boolean)

    true/false

Since:

  • 0.2.0


206
207
208
# File 'lib/dynamoid/associations/many_association.rb', line 206

def ==(other)
  records == Array(other)
end

#associate(hash_key) ⇒ Object


223
224
225
# File 'lib/dynamoid/associations/many_association.rb', line 223

def associate(hash_key)
  source.update_attribute(source_attribute, source_ids.merge(Array(hash_key)))
end

#create(attributes = {}) ⇒ Dynamoid::Document|Array

Create a new instance of the target class, persist it and add directly to the association.

tag.posts.create(title: 'foo')

Several models can be created at once when an array of attributes specified:

tag.posts.create([{ title: 'foo' }, {title: 'bar'} ])

Parameters:

  • attributes (Hash) (defaults to: {})

    attribute values for the new object

Returns:

Since:

  • 0.2.0


146
147
148
# File 'lib/dynamoid/associations/many_association.rb', line 146

def create(attributes = {})
  self << target_class.create(attributes)
end

#create!(attributes = {}) ⇒ Dynamoid::Document|Array

Create a new instance of the target class, persist it and add directly to the association.

tag.posts.create!(title: 'foo')

Several models can be created at once when an array of attributes specified:

tag.posts.create!([{ title: 'foo' }, {title: 'bar'} ])

If the creation fails an exception will be raised.

Parameters:

  • attributes (Hash) (defaults to: {})

    attribute values for the new object

Returns:

Since:

  • 0.2.0


129
130
131
# File 'lib/dynamoid/associations/many_association.rb', line 129

def create!(attributes = {})
  self << target_class.create!(attributes)
end

#delete(object) ⇒ Dynamoid::Document|Array

Delete an object or array of objects from the association.

tag.posts.delete(post)
tag.posts.delete([post1, post2, post3])

This removes their records from the association field on the source, and attempts to remove the source from the target association if it is detected to exist.

It saves both models immediately - the source model and the target one so any not saved changes will be saved as well.

Parameters:

  • object (Dynamoid::Document|Array)

    model (or array of models) to remove from the association

Returns:

Since:

  • 0.2.0


67
68
69
70
71
72
73
# File 'lib/dynamoid/associations/many_association.rb', line 67

def delete(object)
  disassociate(Array(object).collect(&:hash_key))
  if target_association
    Array(object).each { |obj| obj.send(target_association).disassociate(source.hash_key) }
  end
  object
end

#delete_allObject

Deletes all members of the association and removes them from the association.

tag.posts.delete_all

Since:

  • 0.2.0


178
179
180
181
182
# File 'lib/dynamoid/associations/many_association.rb', line 178

def delete_all
  objs = target
  source.update_attribute(source_attribute, nil)
  objs.each(&:delete)
end

#destroy_allObject

Destroys all members of the association and removes them from the association.

tag.posts.destroy_all

Since:

  • 0.2.0


166
167
168
169
170
# File 'lib/dynamoid/associations/many_association.rb', line 166

def destroy_all
  objs = target
  source.update_attribute(source_attribute, nil)
  objs.each(&:destroy)
end

#disassociate(hash_key) ⇒ Object


228
229
230
# File 'lib/dynamoid/associations/many_association.rb', line 228

def disassociate(hash_key)
  source.update_attribute(source_attribute, source_ids - Array(hash_key))
end

#each(&block) ⇒ Dynamoid::Document

Create a new instance of the target class and add it directly to the association. If the create fails an exception will be raised.

Returns:

Since:

  • 0.2.0


156
157
158
# File 'lib/dynamoid/associations/many_association.rb', line 156

def each(&block)
  records.each(&block)
end

#find_targetObject

The records associated to the source.

Returns:

  • the association records; depending on which association this is, either a single instance or an array

Since:

  • 0.2.0


27
28
29
30
31
# File 'lib/dynamoid/associations/many_association.rb', line 27

def find_target
  return [] if source_ids.empty?

  Array(target_class.find(source_ids.to_a, raise_error: false))
end

#include?(object) ⇒ Boolean

Delegate include? to the records.

Returns:

  • (Boolean)

48
49
50
# File 'lib/dynamoid/associations/many_association.rb', line 48

def include?(object)
  records.include?(object)
end

#initialize(*args) ⇒ Object


10
11
12
13
# File 'lib/dynamoid/associations/many_association.rb', line 10

def initialize(*args)
  @query = {}
  super
end

#recordsObject Also known as: all


34
35
36
37
38
39
40
# File 'lib/dynamoid/associations/many_association.rb', line 34

def records
  if query.empty?
    target
  else
    results_with_query(target)
  end
end

#setter(object) ⇒ Dynamoid::Document|Array

Replace an association with object or array of objects. This removes all of the existing associated records and replaces them with the passed object(s), and associates the target association if it is detected to exist.

Parameters:

  • object (Dynamoid::Document)

    the object (or array of objects) to add to the association

Returns:

Since:

  • 0.2.0


108
109
110
111
112
# File 'lib/dynamoid/associations/many_association.rb', line 108

def setter(object)
  target.each { |o| delete(o) }
  self << object
  object
end

#where(args) ⇒ Dynamoid::Association

Naive association filtering.

tag.posts.where(title: 'foo')

It loads lazily all the associated models and checks provided conditions. That's why only equality conditions can be specified.

Parameters:

  • args (Hash)

    A hash of attributes; each must match every returned object's attribute exactly.

Returns:

  • (Dynamoid::Association)

    the association this method was called on (for chaining purposes)

Since:

  • 0.2.0


194
195
196
197
198
199
# File 'lib/dynamoid/associations/many_association.rb', line 194

def where(args)
  filtered = clone
  filtered.query = query.clone
  args.each { |k, v| filtered.query[k] = v }
  filtered
end