Module: Dynomite::Associations::ManyAssociation
- Includes:
- Association, Enumerable
- Included in:
- HasAndBelongsToMany, HasMany
- Defined in:
- lib/dynomite/associations/many_association.rb
Instance Attribute Summary collapse
-
#query ⇒ Object
Returns the value of attribute query.
Attributes included from Association
#loaded, #name, #options, #source
Instance Method Summary collapse
-
#<<(item) ⇒ Dynomite::Item
(also: #associate)
Add an item or array of items to an association.
-
#==(other) ⇒ Boolean
Is this array equal to the association’s records?.
- #associate_one_way(item) ⇒ Object
-
#create(attributes = {}) ⇒ Dynomite::Item|Array
Create a new instance of the target class, persist it and add directly to the association.
-
#create!(attributes = {}) ⇒ Dynomite::Item|Array
Create a new instance of the target class, persist it and add directly to the association.
-
#delete_all ⇒ Object
Deletes all members of the association and removes them from the association.
-
#destroy_all ⇒ Object
Destroys all members of the association and removes them from the association.
-
#disassociate(*items) ⇒ Dynomite::Item|Array
Removes an item or array of items from the association.
- #disassociate_all ⇒ Object
- #disassociate_one_way(item) ⇒ Object
-
#each(&block) ⇒ Dynomite::Item
Create a new instance of the target class and add it directly to the association.
-
#find_target ⇒ Object
The has many association.
-
#include?(item) ⇒ Boolean
Delegate include? to the records.
- #initialize(*args) ⇒ Object
-
#method_missing(method, *args) ⇒ Object
Delegate methods we don’t find directly to the records array.
- #records ⇒ Object (also: #all)
- #relation ⇒ Object
-
#setter(item) ⇒ Dynomite::Item|Array
Replace an association with item or array of items.
-
#where(args) ⇒ Dynomite::Association
Naive association filtering.
Methods included from Association
#coerce_to_id, #coerce_to_item, #declaration_field_name, #declaration_field_type, #loaded?, #reader_target, #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.
233 234 235 236 237 238 239 |
# File 'lib/dynomite/associations/many_association.rb', line 233 def method_missing(method, *args) if records.respond_to?(method) records.send(method, *args) else super end end |
Instance Attribute Details
#query ⇒ Object
Returns the value of attribute query.
6 7 8 |
# File 'lib/dynomite/associations/many_association.rb', line 6 def query @query end |
Instance Method Details
#<<(item) ⇒ Dynomite::Item Also known as: associate
Add an item or array of items to an association.
tag.posts << post
tag.posts << [post1, post2, post3]
This preserves the current records in the association (if any) and adds the item 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.
68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/dynomite/associations/many_association.rb', line 68 def <<(item) item = coerce_to_item(item) # normal relationship associate_one_way(item) # inverse relationship if target_association Array(item).each { |obj| obj.send(target_association).associate_one_way(source) } end item end |
#==(other) ⇒ Boolean
Is this array equal to the association’s records?
228 229 230 |
# File 'lib/dynomite/associations/many_association.rb', line 228 def ==(other) records == Array(other) end |
#associate_one_way(item) ⇒ Object
82 83 84 85 86 87 |
# File 'lib/dynomite/associations/many_association.rb', line 82 def associate_one_way(item) items = Array(item) ids = items.collect { |o| coerce_to_id(o) } ids = source_ids.merge(ids) source.update_attribute_presence(source_attribute, ids) end |
#create(attributes = {}) ⇒ Dynomite::Item|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'} ])
170 171 172 |
# File 'lib/dynomite/associations/many_association.rb', line 170 def create(attributes = {}) self << target_class.create(attributes) end |
#create!(attributes = {}) ⇒ Dynomite::Item|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.
154 155 156 |
# File 'lib/dynomite/associations/many_association.rb', line 154 def create!(attributes = {}) self << target_class.create!(attributes) end |
#delete_all ⇒ Object
Deletes all members of the association and removes them from the association.
tag.posts.delete_all
197 198 199 200 201 |
# File 'lib/dynomite/associations/many_association.rb', line 197 def delete_all objs = target source.update_attribute_presence(source_attribute, nil) objs.each(&:delete) end |
#destroy_all ⇒ Object
Destroys all members of the association and removes them from the association.
tag.posts.destroy_all
186 187 188 189 190 |
# File 'lib/dynomite/associations/many_association.rb', line 186 def destroy_all objs = target source.update_attribute_presence(source_attribute, nil) objs.each(&:destroy) end |
#disassociate(*items) ⇒ Dynomite::Item|Array
Removes an item or array of items from the association.
tag.posts.disassociate(post)
tag.posts.disassociate(post1, post2, post3)
tag.posts.disassociate([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.
104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/dynomite/associations/many_association.rb', line 104 def disassociate(*items) items.flatten! items.map! { |item| coerce_to_item(item) } # normal relationship items.each { |item| disassociate_one_way(item) } # inverse relationship if target_association items.each { |obj| obj.send(target_association).disassociate_one_way(source) } end end |
#disassociate_all ⇒ Object
121 122 123 124 125 126 |
# File 'lib/dynomite/associations/many_association.rb', line 121 def disassociate_all # target is all items. IE: user.posts target.each do |item| disassociate(item) end end |
#disassociate_one_way(item) ⇒ Object
116 117 118 119 |
# File 'lib/dynomite/associations/many_association.rb', line 116 def disassociate_one_way(item) ids = source_ids - Array(coerce_to_id(item)) source.update_attribute_presence(source_attribute, ids) end |
#each(&block) ⇒ Dynomite::Item
Create a new instance of the target class and add it directly to the association. If the create fails an exception will be raised.
177 178 179 |
# File 'lib/dynomite/associations/many_association.rb', line 177 def each(&block) records.each(&block) end |
#find_target ⇒ Object
Returns the has many association. IE: user.posts.
19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/dynomite/associations/many_association.rb', line 19 def find_target return [] if source_ids.empty? # IE: user.posts - target class is Post if target_class.partition_key_field == "id" && target_class.sort_key_field.nil? # Quick find lookup Array(target_class.find(source_ids.to_a, raise_error: false)) else relation.to_a end end |
#include?(item) ⇒ Boolean
Delegate include? to the records.
51 52 53 |
# File 'lib/dynomite/associations/many_association.rb', line 51 def include?(item) records.include?(item) end |
#initialize(*args) ⇒ Object
8 9 10 11 |
# File 'lib/dynomite/associations/many_association.rb', line 8 def initialize(*args) @query = {} super end |
#records ⇒ Object Also known as: all
37 38 39 40 41 42 43 |
# File 'lib/dynomite/associations/many_association.rb', line 37 def records if query.empty? target else results_with_query(target) end end |
#relation ⇒ Object
31 32 33 34 35 |
# File 'lib/dynomite/associations/many_association.rb', line 31 def relation return [] if source_ids.empty? # check again in case user calls relation directly. IE: user.posts.relation # Slow scan lookup because of the in operator target_class.where("id.in": source_ids.to_a) end |
#setter(item) ⇒ Dynomite::Item|Array
Replace an association with item or array of items. This removes all of the existing associated records and replaces them with the passed item(s), and associates the target association if it is detected to exist.
134 135 136 137 138 |
# File 'lib/dynomite/associations/many_association.rb', line 134 def setter(item) target.each { |i| disassociate(i) } self << item item end |
#where(args) ⇒ Dynomite::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.
218 219 220 221 222 223 |
# File 'lib/dynomite/associations/many_association.rb', line 218 def where(args) filtered = clone filtered.query = query.clone args.each { |k, v| filtered.query[k] = v } filtered end |