Class: Parse::RelationCollectionProxy
- Inherits:
-
PointerCollectionProxy
- Object
- CollectionProxy
- PointerCollectionProxy
- Parse::RelationCollectionProxy
- Defined in:
- lib/parse/model/associations/relation_collection_proxy.rb
Overview
The RelationCollectionProxy is similar to a PointerCollectionProxy except that there is no actual “array” object in Parse. Parse treats relation through an intermediary table (a.k.a. join table). Whenever a developer wants the contents of a collection, the foreign table needs to be queried instead. In this scenario, the parse_class: initializer argument should be passed in order to know which remote table needs to be queried in order to fetch the items of the collection.
Unlike managing an array of Pointers, relations in Parse are done throug atomic operations, which have a specific API. The design of this proxy is to maintain two sets of lists, items to be added to the relation and a separate list of items to be removed from the relation.
Because this relationship is based on queryable Parse table, we are also able to not just get all the items in a collection, but also provide additional constraints to get matching items within the relation collection.
When creating a Relation proxy, all the delegate methods defined in the superclasses need to be implemented, in addition to a few others with the key parameter: _relation_query and _commit_relation_updates . :‘key’_relation_query should return a Parse::Query object that is properly tied to the foreign table class related to this object column. Example, if an Artist has many Song objects, then the query to be returned by this method should be a Parse::Query for the class ‘Song’. Because relation changes are separate from object changes, you can call save on a relation collection to save the current add and remove operations. Because the delegate needs to be informed of the changes being committed, it will be notified through :‘key’_commit_relation_updates message. The delegate is also in charge of clearing out the change information for the collection if saved successfully.
Instance Attribute Summary collapse
-
#additions ⇒ Object
readonly
The objects that have been newly added to this collection.
- #removals ⇒ Array<Parse::Object> readonly
Attributes inherited from PointerCollectionProxy
Attributes inherited from CollectionProxy
#collection, #delegate, #key, #loaded, #parse_class
Instance Method Summary collapse
- #<<(*list) ⇒ Object
-
#add(*items) ⇒ Array<Parse::Object>
Add Parse::Objects to the relation.
-
#add!(*items) ⇒ Object
Atomically add a set of Parse::Objects to this relation.
-
#add_unique!(*items) ⇒ Object
Atomically add a set of Parse::Objects to this relation.
-
#all(constraints = {}, &block) ⇒ Object
You can get items within the collection relation filtered by a specific set of query constraints.
-
#initialize(collection = nil, delegate: nil, key: nil, parse_class: nil) ⇒ RelationCollectionProxy
constructor
A new instance of RelationCollectionProxy.
-
#limit(count) ⇒ Object
Return a query with limit applied - allows chaining like relation.limit(5).all.
-
#query(constraints = {}) ⇒ Object
Ask the delegate to return a query for this collection type.
-
#remove(*items) ⇒ Array<Parse::Object>
Removes Parse::Objects from the relation.
-
#remove!(*items) ⇒ Object
Atomically remove a set of Parse::Objects to this relation.
-
#save ⇒ Object
Save the changes to the relation.
Methods inherited from PointerCollectionProxy
Methods inherited from CollectionProxy
#&, #+, #-, #==, #add_unique, #as_json, #changes_applied!, #clear, #clear_changes!, #count, #destroy!, #each, #empty?, #first, #flatten, #forward, #last, #loaded?, #map, #notify_will_change!, #parse_objects, #parse_pointers, #reload!, #reset!, #rollback!, #second, #select, #set_collection!, #to_a, #uniq, #uniq!, #|
Constructor Details
#initialize(collection = nil, delegate: nil, key: nil, parse_class: nil) ⇒ RelationCollectionProxy
Returns a new instance of RelationCollectionProxy.
48 49 50 51 52 |
# File 'lib/parse/model/associations/relation_collection_proxy.rb', line 48 def initialize(collection = nil, delegate: nil, key: nil, parse_class: nil) super @additions = [] @removals = [] end |
Instance Attribute Details
#additions ⇒ Object (readonly)
The objects that have been newly added to this collection
46 47 48 |
# File 'lib/parse/model/associations/relation_collection_proxy.rb', line 46 def additions @additions end |
#removals ⇒ Array<Parse::Object> (readonly)
46 |
# File 'lib/parse/model/associations/relation_collection_proxy.rb', line 46 attr_reader :additions, :removals |
Instance Method Details
#<<(*list) ⇒ Object
172 173 174 175 |
# File 'lib/parse/model/associations/relation_collection_proxy.rb', line 172 def <<(*list) list.each { |d| add(d) } @collection end |
#add(parse_object) ⇒ Array<Parse::Object> #add(parse_objects) ⇒ Array<Parse::Object>
Add Parse::Objects to the relation.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/parse/model/associations/relation_collection_proxy.rb', line 97 def add(*items) items = items.flatten.parse_objects return @collection if items.empty? notify_will_change! additions_will_change! removals_will_change! # take all the items items.each do |item| @additions.push item @collection.push item #cleanup @removals.delete item end @collection end |
#add!(*items) ⇒ Object
Atomically add a set of Parse::Objects to this relation. This is done by making the API request directly with Parse server; the local object is not updated with changes.
140 141 142 143 144 |
# File 'lib/parse/model/associations/relation_collection_proxy.rb', line 140 def add!(*items) return false unless @delegate.respond_to?(:op_add_relation!) items = items.flatten.parse_pointers @delegate.send :op_add_relation!, @key, items end |
#add_unique!(*items) ⇒ Object
Atomically add a set of Parse::Objects to this relation. This is done by making the API request directly with Parse server; the local object is not updated with changes.
149 150 151 152 153 |
# File 'lib/parse/model/associations/relation_collection_proxy.rb', line 149 def add_unique!(*items) return false unless @delegate.respond_to?(:op_add_relation!) items = items.flatten.parse_pointers @delegate.send :op_add_relation!, @key, items end |
#all(constraints = {}, &block) ⇒ Object
You can get items within the collection relation filtered by a specific set of query constraints.
56 57 58 59 60 61 62 63 64 |
# File 'lib/parse/model/associations/relation_collection_proxy.rb', line 56 def all(constraints = {}, &block) q = query({ limit: :max }.merge(constraints)) if block_given? # if we have a query, then use the Proc with it (more efficient) return q.present? ? q.results(&block) : collection.each(&block) end # if no block given, get all the results q.present? ? q.results : collection end |
#limit(count) ⇒ Object
Return a query with limit applied - allows chaining like relation.limit(5).all
85 86 87 |
# File 'lib/parse/model/associations/relation_collection_proxy.rb', line 85 def limit(count) query(limit: count) end |
#query(constraints = {}) ⇒ Object
Ask the delegate to return a query for this collection type
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/parse/model/associations/relation_collection_proxy.rb', line 67 def query(constraints = {}) q = forward :"#{@key}_relation_query" # Apply constraints if provided (excluding limit which is handled differently) query_constraints = constraints.except(:limit) if query_constraints.present? q = q.where(query_constraints) end # Apply limit if specified if constraints[:limit].present? q = q.limit(constraints[:limit]) end q end |
#remove(parse_object) ⇒ Array<Parse::Object> #remove(parse_objects) ⇒ Array<Parse::Object>
Removes Parse::Objects from the relation.
122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/parse/model/associations/relation_collection_proxy.rb', line 122 def remove(*items) items = items.flatten.parse_objects return @collection if items.empty? notify_will_change! additions_will_change! removals_will_change! items.each do |item| @removals.push item @collection.delete item # remove it from any add operations @additions.delete item end @collection end |
#remove!(*items) ⇒ Object
Atomically remove a set of Parse::Objects to this relation. This is done by making the API request directly with Parse server; the local object is not updated with changes.
158 159 160 161 162 |
# File 'lib/parse/model/associations/relation_collection_proxy.rb', line 158 def remove!(*items) return false unless @delegate.respond_to?(:op_remove_relation!) items = items.flatten.parse_pointers @delegate.send :op_remove_relation!, @key, items end |
#save ⇒ Object
Save the changes to the relation
165 166 167 168 169 |
# File 'lib/parse/model/associations/relation_collection_proxy.rb', line 165 def save unless @removals.empty? && @additions.empty? forward :"#{@key}_commit_relation_updates" end end |