parse-stack 1.8.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.solargraph.yml +23 -0
  3. data/.travis.yml +0 -1
  4. data/Gemfile +13 -12
  5. data/Gemfile.lock +88 -51
  6. data/README.md +2 -4
  7. data/Rakefile +14 -14
  8. data/lib/parse/api/aggregate.rb +4 -7
  9. data/lib/parse/api/all.rb +1 -1
  10. data/lib/parse/api/analytics.rb +0 -3
  11. data/lib/parse/api/batch.rb +3 -5
  12. data/lib/parse/api/cloud_functions.rb +0 -3
  13. data/lib/parse/api/config.rb +0 -4
  14. data/lib/parse/api/files.rb +3 -7
  15. data/lib/parse/api/hooks.rb +4 -8
  16. data/lib/parse/api/objects.rb +7 -12
  17. data/lib/parse/api/push.rb +0 -4
  18. data/lib/parse/api/schema.rb +2 -6
  19. data/lib/parse/api/server.rb +4 -7
  20. data/lib/parse/api/sessions.rb +2 -5
  21. data/lib/parse/api/users.rb +9 -14
  22. data/lib/parse/client.rb +54 -50
  23. data/lib/parse/client/authentication.rb +29 -33
  24. data/lib/parse/client/batch.rb +8 -11
  25. data/lib/parse/client/body_builder.rb +19 -20
  26. data/lib/parse/client/caching.rb +23 -28
  27. data/lib/parse/client/protocol.rb +11 -12
  28. data/lib/parse/client/request.rb +4 -6
  29. data/lib/parse/client/response.rb +5 -7
  30. data/lib/parse/model/acl.rb +14 -12
  31. data/lib/parse/model/associations/belongs_to.rb +14 -21
  32. data/lib/parse/model/associations/collection_proxy.rb +328 -329
  33. data/lib/parse/model/associations/has_many.rb +18 -25
  34. data/lib/parse/model/associations/has_one.rb +6 -11
  35. data/lib/parse/model/associations/pointer_collection_proxy.rb +5 -8
  36. data/lib/parse/model/associations/relation_collection_proxy.rb +5 -9
  37. data/lib/parse/model/bytes.rb +8 -10
  38. data/lib/parse/model/classes/installation.rb +2 -4
  39. data/lib/parse/model/classes/product.rb +2 -5
  40. data/lib/parse/model/classes/role.rb +3 -5
  41. data/lib/parse/model/classes/session.rb +2 -5
  42. data/lib/parse/model/classes/user.rb +20 -16
  43. data/lib/parse/model/core/actions.rb +31 -46
  44. data/lib/parse/model/core/builder.rb +6 -6
  45. data/lib/parse/model/core/errors.rb +0 -1
  46. data/lib/parse/model/core/fetching.rb +45 -50
  47. data/lib/parse/model/core/properties.rb +51 -66
  48. data/lib/parse/model/core/querying.rb +291 -294
  49. data/lib/parse/model/core/schema.rb +89 -92
  50. data/lib/parse/model/date.rb +16 -17
  51. data/lib/parse/model/file.rb +171 -174
  52. data/lib/parse/model/geopoint.rb +12 -16
  53. data/lib/parse/model/model.rb +31 -37
  54. data/lib/parse/model/object.rb +47 -53
  55. data/lib/parse/model/pointer.rb +177 -176
  56. data/lib/parse/model/push.rb +8 -10
  57. data/lib/parse/model/shortnames.rb +1 -2
  58. data/lib/parse/model/time_zone.rb +3 -5
  59. data/lib/parse/query.rb +34 -35
  60. data/lib/parse/query/constraint.rb +4 -6
  61. data/lib/parse/query/constraints.rb +21 -29
  62. data/lib/parse/query/operation.rb +8 -11
  63. data/lib/parse/query/ordering.rb +45 -49
  64. data/lib/parse/stack.rb +11 -12
  65. data/lib/parse/stack/generators/rails.rb +28 -30
  66. data/lib/parse/stack/generators/templates/model.erb +5 -6
  67. data/lib/parse/stack/generators/templates/model_installation.rb +0 -1
  68. data/lib/parse/stack/generators/templates/model_role.rb +0 -1
  69. data/lib/parse/stack/generators/templates/model_session.rb +0 -1
  70. data/lib/parse/stack/generators/templates/model_user.rb +0 -1
  71. data/lib/parse/stack/generators/templates/parse.rb +9 -9
  72. data/lib/parse/stack/generators/templates/webhooks.rb +1 -2
  73. data/lib/parse/stack/railtie.rb +2 -4
  74. data/lib/parse/stack/tasks.rb +70 -86
  75. data/lib/parse/stack/version.rb +1 -1
  76. data/lib/parse/webhooks.rb +19 -26
  77. data/lib/parse/webhooks/payload.rb +26 -28
  78. data/lib/parse/webhooks/registration.rb +23 -31
  79. data/parse-stack.gemspec +25 -25
  80. data/parse-stack.png +0 -0
  81. metadata +13 -7
  82. data/.github/parse-ruby-sdk.png +0 -0
@@ -1,7 +1,6 @@
1
1
  # encoding: UTF-8
2
2
  # frozen_string_literal: true
3
3
 
4
-
5
4
  module Parse
6
5
 
7
6
  # This class allows you to define custom data types for your model fields. You
@@ -33,7 +32,6 @@ module Parse
33
32
  def as_json(*args)
34
33
  {}.as_json
35
34
  end
36
-
37
35
  end
38
36
 
39
37
  # An ACL represents the dirty-trackable Parse Permissions object used for
@@ -131,6 +129,7 @@ module Parse
131
129
  def permissions
132
130
  @permissions ||= {}
133
131
  end
132
+
134
133
  # The key field value for public permissions.
135
134
  PUBLIC = "*".freeze
136
135
 
@@ -162,7 +161,7 @@ module Parse
162
161
  # @return [ACL::Permission]
163
162
  # @see ACL::Permission
164
163
  def self.permission(read, write = nil)
165
- ACL::Permission.new(read, write)
164
+ ACL::Permission.new(read, write)
166
165
  end
167
166
  # Determines whether two ACLs or a Parse-ACL hash is equivalent to this object.
168
167
  # @example
@@ -195,6 +194,7 @@ module Parse
195
194
  apply(PUBLIC, read, write)
196
195
  permissions[PUBLIC]
197
196
  end
197
+
198
198
  alias_method :world, :everyone
199
199
 
200
200
  # Calls `acl_will_change!` on the delegate when the permissions have changed.
@@ -236,7 +236,7 @@ module Parse
236
236
  # @return [Hash] the current set of permissions.
237
237
  # @see #apply_role
238
238
  def apply(id, read = nil, write = nil)
239
- return apply_role(id,read,write) if id.is_a?(Parse::Role)
239
+ return apply_role(id, read, write) if id.is_a?(Parse::Role)
240
240
  id = id.id if id.is_a?(Parse::Pointer)
241
241
  unless id.present?
242
242
  raise ArgumentError, "Invalid argument applying ACLs: must be either objectId, role or :public"
@@ -254,7 +254,8 @@ module Parse
254
254
  end
255
255
 
256
256
  permissions
257
- end; alias_method :add, :apply
257
+ end;
258
+ alias_method :add, :apply
258
259
 
259
260
  # Apply a {Parse::Role} to this ACL.
260
261
  # @overload apply_role(role, read = nil, write = nil)
@@ -268,7 +269,8 @@ module Parse
268
269
  def apply_role(name, read = nil, write = nil)
269
270
  name = name.name if name.is_a?(Parse::Role)
270
271
  apply("role:#{name}", read, write)
271
- end; alias_method :add_role, :apply_role
272
+ end;
273
+ alias_method :add_role, :apply_role
272
274
 
273
275
  # Used for object conversion when formatting the input/output value in
274
276
  # Parse::Object properties
@@ -286,7 +288,7 @@ module Parse
286
288
  # all privileges
287
289
  # @return [Hash]
288
290
  def attributes
289
- permissions.select {|k,v| v.present? }.as_json
291
+ permissions.select { |k, v| v.present? }.as_json
290
292
  end
291
293
 
292
294
  # @!visibility private
@@ -294,8 +296,8 @@ module Parse
294
296
  return unless h.is_a?(Hash)
295
297
  will_change!
296
298
  @permissions ||= {}
297
- h.each do |k,v|
298
- apply(k,v)
299
+ h.each do |k, v|
300
+ apply(k, v)
299
301
  end
300
302
  end
301
303
 
@@ -306,7 +308,7 @@ module Parse
306
308
 
307
309
  # @return [Hash]
308
310
  def as_json(*args)
309
- permissions.select {|k,v| v.present? }.as_json
311
+ permissions.select { |k, v| v.present? }.as_json
310
312
  end
311
313
 
312
314
  # @return [Boolean] true if there are any permissions.
@@ -330,7 +332,8 @@ module Parse
330
332
  def master_key_only!
331
333
  will_change!
332
334
  @permissions = {}
333
- end; alias_method :clear!, :master_key_only!
335
+ end;
336
+ alias_method :clear!, :master_key_only!
334
337
 
335
338
  # Grants read permission on all existing users and roles attached to this object.
336
339
  # @example
@@ -530,7 +533,6 @@ module Parse
530
533
  def no_write!
531
534
  @write = false
532
535
  end
533
-
534
536
  end
535
537
  end
536
538
  end
@@ -1,11 +1,10 @@
1
1
  # encoding: UTF-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require_relative '../pointer'
5
- require_relative 'collection_proxy'
6
- require_relative 'pointer_collection_proxy'
7
- require_relative 'relation_collection_proxy'
8
-
4
+ require_relative "../pointer"
5
+ require_relative "collection_proxy"
6
+ require_relative "pointer_collection_proxy"
7
+ require_relative "relation_collection_proxy"
9
8
 
10
9
  module Parse
11
10
  # Defines all the types of Parse object associations.
@@ -120,7 +119,7 @@ module Parse
120
119
 
121
120
  # These items are added as attributes with the special data type of :pointer
122
121
  def belongs_to(key, opts = {})
123
- opts = {as: key, field: key.to_s.camelize(:lower), required: false}.merge(opts)
122
+ opts = { as: key, field: key.to_s.camelize(:lower), required: false }.merge(opts)
124
123
  klassName = opts[:as].to_parse_class
125
124
  parse_field = opts[:field].to_sym
126
125
 
@@ -138,13 +137,13 @@ module Parse
138
137
  end
139
138
  # store this attribute in the attributes hash with the proper remote column name.
140
139
  # we know the type is pointer.
141
- self.attributes.merge!( parse_field => :pointer )
140
+ self.attributes.merge!(parse_field => :pointer)
142
141
  # Add them to our list of pointer references
143
- self.references.merge!( parse_field => klassName )
142
+ self.references.merge!(parse_field => klassName)
144
143
  # Add them to the list of fields in our class model
145
- self.fields.merge!( key => :pointer, parse_field => :pointer )
144
+ self.fields.merge!(key => :pointer, parse_field => :pointer)
146
145
  # Mapping between local attribute name and the remote column name
147
- self.field_map.merge!( key => parse_field )
146
+ self.field_map.merge!(key => parse_field)
148
147
 
149
148
  # used for dirty tracking
150
149
  define_attribute_methods key
@@ -154,7 +153,6 @@ module Parse
154
153
 
155
154
  # We generate the getter method
156
155
  define_method(key) do
157
-
158
156
  val = instance_variable_get ivar
159
157
  # We provide autofetch functionality. If the value is nil and the
160
158
  # current Parse::Object is a pointer, then let's auto fetch it
@@ -166,8 +164,8 @@ module Parse
166
164
  # if for some reason we retrieved either from store or fetching a
167
165
  # hash, lets try to buid a Pointer of that type.
168
166
 
169
- if val.is_a?(Hash) && ( val["__type"] == "Pointer" || val["__type"] == "Object" )
170
- val = Parse::Object.build val, ( val[Parse::Model::KEY_CLASS_NAME] || klassName )
167
+ if val.is_a?(Hash) && (val["__type"] == "Pointer" || val["__type"] == "Object")
168
+ val = Parse::Object.build val, (val[Parse::Model::KEY_CLASS_NAME] || klassName)
171
169
  instance_variable_set ivar, val
172
170
  end
173
171
  val
@@ -190,12 +188,12 @@ module Parse
190
188
  define_method(set_attribute_method) do |val, track = true|
191
189
  if val == Parse::Properties::DELETE_OP
192
190
  val = nil
193
- elsif val.is_a?(Hash) && ( val["__type"] == "Pointer" || val["__type"] == "Object" )
194
- val = Parse::Object.build val, ( val[Parse::Model::KEY_CLASS_NAME] || klassName )
191
+ elsif val.is_a?(Hash) && (val["__type"] == "Pointer" || val["__type"] == "Object")
192
+ val = Parse::Object.build val, (val[Parse::Model::KEY_CLASS_NAME] || klassName)
195
193
  end
196
194
 
197
195
  if track == true
198
- send will_change_method unless val == instance_variable_get( ivar )
196
+ send will_change_method unless val == instance_variable_get(ivar)
199
197
  end
200
198
 
201
199
  # Never set an object that is not a Parse::Pointer
@@ -204,7 +202,6 @@ module Parse
204
202
  else
205
203
  warn "[#{self.class}] Invalid value #{val} set for belongs_to field #{key}"
206
204
  end
207
-
208
205
  end
209
206
  # don't create method aliases if the fields are the same
210
207
  return if parse_field.to_sym == key.to_sym
@@ -216,12 +213,8 @@ module Parse
216
213
  elsif parse_field.to_sym != :objectId
217
214
  warn "Alias belongs_to method #{self}##{parse_field} already defined."
218
215
  end
219
-
220
216
  end
221
-
222
217
  end # ClassMethod
223
-
224
218
  end #BelongsTo
225
219
  end #Associations
226
-
227
220
  end
@@ -1,379 +1,378 @@
1
1
  # encoding: UTF-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'active_model'
5
- require 'active_support'
6
- require 'active_support/inflector'
7
- require 'active_support/core_ext/object'
8
- require_relative '../pointer'
9
-
4
+ require "active_model"
5
+ require "active_support"
6
+ require "active_support/inflector"
7
+ require "active_support/core_ext/object"
8
+ require_relative "../pointer"
10
9
 
11
10
  module Parse
12
- # We use a delegate pattern to send notifications to the parent whenever the content of the internal array changes.
13
- # The main requirement to using the proxy is to provide the list of initial items if any,
14
- # the owner to be notified and the name of the attribute 'key'. With that, anytime the array
15
- # will change, we will notify the delegate by sending :'key'_will_change! . The proxy can also
16
- # be lazy when fetching the contents of the collection. Whenever the collection is accessed and
17
- # the list is in a "not loaded" state (empty and loaded == false), we will send :'key_fetch!' to the delegate in order to
18
- # populate the collection.
19
-
20
- # A CollectionProxy is a special type of array wrapper that notifies a delegate
21
- # object about changes to the array in order to perform dirty tracking. This is
22
- # used for all Array properties in Parse::Objects. Subclasses of {CollectionProxy} are
23
- # also available for supporting different association types such as an array of Parse pointers
24
- # and Parse relations.
11
+ # We use a delegate pattern to send notifications to the parent whenever the content of the internal array changes.
12
+ # The main requirement to using the proxy is to provide the list of initial items if any,
13
+ # the owner to be notified and the name of the attribute 'key'. With that, anytime the array
14
+ # will change, we will notify the delegate by sending :'key'_will_change! . The proxy can also
15
+ # be lazy when fetching the contents of the collection. Whenever the collection is accessed and
16
+ # the list is in a "not loaded" state (empty and loaded == false), we will send :'key_fetch!' to the delegate in order to
17
+ # populate the collection.
18
+
19
+ # A CollectionProxy is a special type of array wrapper that notifies a delegate
20
+ # object about changes to the array in order to perform dirty tracking. This is
21
+ # used for all Array properties in Parse::Objects. Subclasses of {CollectionProxy} are
22
+ # also available for supporting different association types such as an array of Parse pointers
23
+ # and Parse relations.
24
+ # @see PointerCollectionProxy
25
+ # @see RelationCollectionProxy
26
+ class CollectionProxy
27
+ include ::ActiveModel::Model
28
+ include ::ActiveModel::Dirty
29
+ include ::Enumerable
30
+
31
+ # @!attribute [r] delegate
32
+ # The object to be notified of changes to the collection.
33
+ # @return [Object]
34
+
35
+ # @!attribute [rw] loaded
36
+ # @return [Boolean] true/false whether the collection has been loaded.
37
+
38
+ # @!attribute [r] parse_class
39
+ # For some subclasses, this helps typecast the items in the collection.
40
+ # @return [String]
41
+
42
+ # @!attribute [r] key
43
+ # the name of the property key to use when sending notifications for _will_change! and _fetch!
44
+ # @return [String]
45
+
46
+ attr_accessor :collection, :delegate, :loaded, :parse_class
47
+ attr_reader :delegate, :key
48
+
49
+ # This is to use dirty tracking within the proxy
50
+ define_attribute_methods :collection
51
+
52
+ # Create a new CollectionProxy instance.
53
+ # @param collection [Array] the initial items to add to the collection.
54
+ # @param delegate [Object] the owner of the object that will receive the notifications.
55
+ # @param key [Symbol] the name of the key to use when sending notifications for _will_change! and _fetch!
56
+ # @param parse_class [String] (Optional) the Parse class type are the items of the collection.
57
+ # This is used to typecast the objects in the array to a particular Parse Object type.
25
58
  # @see PointerCollectionProxy
26
59
  # @see RelationCollectionProxy
27
- class CollectionProxy
28
- include ::ActiveModel::Model
29
- include ::ActiveModel::Dirty
30
- include ::Enumerable
31
-
32
- # @!attribute [r] delegate
33
- # The object to be notified of changes to the collection.
34
- # @return [Object]
35
-
36
- # @!attribute [rw] loaded
37
- # @return [Boolean] true/false whether the collection has been loaded.
38
-
39
- # @!attribute [r] parse_class
40
- # For some subclasses, this helps typecast the items in the collection.
41
- # @return [String]
42
-
43
- # @!attribute [r] key
44
- # the name of the property key to use when sending notifications for _will_change! and _fetch!
45
- # @return [String]
46
-
47
- attr_accessor :collection, :delegate, :loaded, :parse_class
48
- attr_reader :delegate, :key
49
-
50
- # This is to use dirty tracking within the proxy
51
- define_attribute_methods :collection
52
-
53
- # Create a new CollectionProxy instance.
54
- # @param collection [Array] the initial items to add to the collection.
55
- # @param delegate [Object] the owner of the object that will receive the notifications.
56
- # @param key [Symbol] the name of the key to use when sending notifications for _will_change! and _fetch!
57
- # @param parse_class [String] (Optional) the Parse class type are the items of the collection.
58
- # This is used to typecast the objects in the array to a particular Parse Object type.
59
- # @see PointerCollectionProxy
60
- # @see RelationCollectionProxy
61
- def initialize(collection = nil, delegate: nil, key: nil, parse_class: nil)
62
- @delegate = delegate
63
- @key = key.to_sym if key.present?
64
- @collection = collection.is_a?(Array) ? collection : []
65
- @loaded = @collection.count > 0
66
- @parse_class = parse_class
67
- end
68
-
69
- # true if the collection has been loaded
70
- def loaded?
71
- @loaded
72
- end
73
-
74
- # Forward a method call to the delegate.
75
- # @param method [Symbol] the name of the method to forward
76
- # @param params [Object] method parameters
77
- # @return [Object] the return value from the forwarded method.
78
- def forward(method, params = nil)
79
- return unless @delegate && @delegate.respond_to?(method)
80
- params.nil? ? @delegate.send(method) : @delegate.send(method, params)
81
- end
82
-
83
- # Reset the state of the collection.
84
- def reset!
85
- @loaded = false
86
- clear
87
- end
88
-
89
- # @return [Boolean] true if two collection proxies have similar items.
90
- def ==(other_list)
91
- if other_list.is_a?(Array)
92
- return @collection == other_list
93
- elsif other_list.is_a?(Parse::CollectionProxy)
94
- return @collection == other_list.instance_variable_get(:@collection)
95
- end
96
- end
60
+ def initialize(collection = nil, delegate: nil, key: nil, parse_class: nil)
61
+ @delegate = delegate
62
+ @key = key.to_sym if key.present?
63
+ @collection = collection.is_a?(Array) ? collection : []
64
+ @loaded = @collection.count > 0
65
+ @parse_class = parse_class
66
+ end
97
67
 
98
- # Reload and restore the collection to its original set of items.
99
- def reload!
100
- reset!
101
- collection #force reload
102
- end
68
+ # true if the collection has been loaded
69
+ def loaded?
70
+ @loaded
71
+ end
103
72
 
104
- # clear all items in the collection
105
- def clear
106
- @collection.clear
107
- end
73
+ # Forward a method call to the delegate.
74
+ # @param method [Symbol] the name of the method to forward
75
+ # @param params [Object] method parameters
76
+ # @return [Object] the return value from the forwarded method.
77
+ def forward(method, params = nil)
78
+ return unless @delegate && @delegate.respond_to?(method)
79
+ params.nil? ? @delegate.send(method) : @delegate.send(method, params)
80
+ end
108
81
 
109
- # @return [Array]
110
- def to_a
111
- collection.to_a
112
- end; alias_method :to_ary, :to_a
82
+ # Reset the state of the collection.
83
+ def reset!
84
+ @loaded = false
85
+ clear
86
+ end
113
87
 
114
- # Set the internal collection of items *without* dirty tracking or
115
- # change notifications.
116
- # @return [Array] the collection
117
- def set_collection!(list)
118
- @collection = list
88
+ # @return [Boolean] true if two collection proxies have similar items.
89
+ def ==(other_list)
90
+ if other_list.is_a?(Array)
91
+ return @collection == other_list
92
+ elsif other_list.is_a?(Parse::CollectionProxy)
93
+ return @collection == other_list.instance_variable_get(:@collection)
119
94
  end
95
+ end
120
96
 
121
- # @!attribute [rw] collection
122
- # The internal backing store of the collection containing the content. This value is lazily
123
- # loaded for some subclasses.
124
- # @note If you modify this directly, it is highly recommended that you
125
- # call {CollectionProxy#notify_will_change!} to notify the dirty tracking system.
126
- # @return [Array] contents of the collection.
127
- def collection
128
- if @collection.empty? && @loaded == false
129
- @collection = forward( :"#{@key}_fetch!" ) || @collection || []
130
- @loaded = true
131
- end
132
-
133
- @collection
134
- end
97
+ # Reload and restore the collection to its original set of items.
98
+ def reload!
99
+ reset!
100
+ collection #force reload
101
+ end
135
102
 
136
- def collection=(c)
137
- notify_will_change!
138
- @collection = c
139
- end
103
+ # clear all items in the collection
104
+ def clear
105
+ @collection.clear
106
+ end
140
107
 
141
- # Add items to the collection
142
- # @param items [Array] items to add
143
- def add(*items)
144
- notify_will_change! if items.count > 0
145
- items.each do |item|
146
- collection.push item
147
- end
148
- @collection
149
- end; alias_method :push, :add
150
-
151
- # Add items to the collection if they don't already exist
152
- # @param items [Array] items to uniquely add
153
- # @return [Array] the collection.
154
- def add_unique(*items)
155
- return unless items.count > 0
156
- notify_will_change!
157
- @collection = collection | items.flatten
158
- @collection
159
- end; alias_method :push_unique, :add_unique
160
-
161
- # Set Union - Returns a new array by joining two arrays, excluding
162
- # any duplicates and preserving the order from the original array.
163
- # It compares elements using their hash and eql? methods for efficiency.
164
- # See {https://docs.ruby-lang.org/en/2.0.0/Array.html#method-i-hash Array#|}
165
- # @example
166
- # [ "a", "b", "c" ] | [ "c", "d", "a" ] #=> [ "a", "b", "c", "d" ]
167
- # @param items [Array] items to uniquely add
168
- # @see #add_unique
169
- # @return [Array] array with unique items
170
- def |(items)
171
- collection | [items].flatten
172
- end
108
+ # @return [Array]
109
+ def to_a
110
+ collection.to_a
111
+ end;
112
+ alias_method :to_ary, :to_a
113
+
114
+ # Set the internal collection of items *without* dirty tracking or
115
+ # change notifications.
116
+ # @return [Array] the collection
117
+ def set_collection!(list)
118
+ @collection = list
119
+ end
173
120
 
174
- # Set Intersection - Returns a new array containing unique elements common
175
- # to the two arrays. The order is preserved from the original array.
176
- #
177
- # It compares elements using their hash and eql? methods for efficiency.
178
- # See {https://ruby-doc.org/core-2.4.1/Array.html#method-i-26 Array#&}
179
- # @example
180
- # [ 1, 1, 3, 5 ] & [ 3, 2, 1 ] #=> [ 1, 3 ]
181
- # [ 'a', 'b', 'b', 'z' ] & [ 'a', 'b', 'c' ] #=> [ 'a', 'b' ]
182
- # @param other_ary [Array]
183
- # @return [Array] intersection array
184
- def &(other_ary)
185
- collection & [other_ary].flatten
121
+ # @!attribute [rw] collection
122
+ # The internal backing store of the collection containing the content. This value is lazily
123
+ # loaded for some subclasses.
124
+ # @note If you modify this directly, it is highly recommended that you
125
+ # call {CollectionProxy#notify_will_change!} to notify the dirty tracking system.
126
+ # @return [Array] contents of the collection.
127
+ def collection
128
+ if @collection.empty? && @loaded == false
129
+ @collection = forward(:"#{@key}_fetch!") || @collection || []
130
+ @loaded = true
186
131
  end
187
132
 
188
- # Alias {https://ruby-doc.org/core-2.4.1/Array.html#method-i-2D Array Difference}.
189
- # Returns a new array that is a copy of the original array, removing any
190
- # items that also appear in other_ary. The order is preserved from the
191
- # original array.
192
- # @example
193
- # [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ]
194
- # @param other_ary [Array]
195
- # @return [Array] delta array
196
- def -(other_ary)
197
- collection - [other_ary].flatten
198
- end
133
+ @collection
134
+ end
199
135
 
200
- # Alias {https://ruby-doc.org/core-2.4.1/Array.html#method-i-2B Array Concatenation}.
201
- # Returns a new array built by concatenating the two arrays together to
202
- # produce a third array.
203
- # @example
204
- # [ 1, 2, 3 ] + [ 4, 5 ] #=> [ 1, 2, 3, 4, 5 ]
205
- # @param other_ary [Array]
206
- # @return [Array] concatenated array
207
- def +(other_ary)
208
- collection + [other_ary].flatten.to_a
209
- end
136
+ def collection=(c)
137
+ notify_will_change!
138
+ @collection = c
139
+ end
210
140
 
211
- # Alias {https://ruby-doc.org/core-2.4.1/Array.html#method-i-flatten Array flattening}.
212
- # @return [Array] a flattened one-dimensional array
213
- def flatten
214
- collection.flatten
215
- end
141
+ # Add items to the collection
142
+ # @param items [Array] items to add
143
+ def add(*items)
144
+ notify_will_change! if items.count > 0
145
+ items.each do |item|
146
+ collection.push item
147
+ end
148
+ @collection
149
+ end;
150
+ alias_method :push, :add
151
+
152
+ # Add items to the collection if they don't already exist
153
+ # @param items [Array] items to uniquely add
154
+ # @return [Array] the collection.
155
+ def add_unique(*items)
156
+ return unless items.count > 0
157
+ notify_will_change!
158
+ @collection = collection | items.flatten
159
+ @collection
160
+ end;
161
+ alias_method :push_unique, :add_unique
162
+
163
+ # Set Union - Returns a new array by joining two arrays, excluding
164
+ # any duplicates and preserving the order from the original array.
165
+ # It compares elements using their hash and eql? methods for efficiency.
166
+ # See {https://docs.ruby-lang.org/en/2.0.0/Array.html#method-i-hash Array#|}
167
+ # @example
168
+ # [ "a", "b", "c" ] | [ "c", "d", "a" ] #=> [ "a", "b", "c", "d" ]
169
+ # @param items [Array] items to uniquely add
170
+ # @see #add_unique
171
+ # @return [Array] array with unique items
172
+ def |(items)
173
+ collection | [items].flatten
174
+ end
216
175
 
217
- # Remove items from the collection
218
- # @param items [Array] items to remove
219
- def remove(*items)
220
- notify_will_change! if items.count > 0
221
- items.each do |item|
222
- collection.delete item
223
- end
224
- @collection
225
- end; alias_method :delete, :remove
226
-
227
- # Atomically adds all items from the array.
228
- # This request is sent directly to the Parse backend.
229
- # @param items [Array] items to uniquely add
230
- # @see #add_unique!
231
- def add!(*items)
232
- return false unless @delegate.respond_to?(:op_add!)
233
- @delegate.send :op_add!, @key, items.flatten
234
- reset!
235
- end
176
+ # Set Intersection - Returns a new array containing unique elements common
177
+ # to the two arrays. The order is preserved from the original array.
178
+ #
179
+ # It compares elements using their hash and eql? methods for efficiency.
180
+ # See {https://ruby-doc.org/core-2.4.1/Array.html#method-i-26 Array#&}
181
+ # @example
182
+ # [ 1, 1, 3, 5 ] & [ 3, 2, 1 ] #=> [ 1, 3 ]
183
+ # [ 'a', 'b', 'b', 'z' ] & [ 'a', 'b', 'c' ] #=> [ 'a', 'b' ]
184
+ # @param other_ary [Array]
185
+ # @return [Array] intersection array
186
+ def &(other_ary)
187
+ collection & [other_ary].flatten
188
+ end
236
189
 
237
- # Atomically adds all items from the array that are not already part of the collection.
238
- # This request is sent directly to the Parse backend.
239
- # @param items [Array] items to uniquely add
240
- # @see #add!
241
- def add_unique!(*items)
242
- return false unless @delegate.respond_to?(:op_add_unique!)
243
- @delegate.send :op_add_unique!, @key, items.flatten
244
- reset!
245
- end
190
+ # Alias {https://ruby-doc.org/core-2.4.1/Array.html#method-i-2D Array Difference}.
191
+ # Returns a new array that is a copy of the original array, removing any
192
+ # items that also appear in other_ary. The order is preserved from the
193
+ # original array.
194
+ # @example
195
+ # [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ]
196
+ # @param other_ary [Array]
197
+ # @return [Array] delta array
198
+ def -(other_ary)
199
+ collection - [other_ary].flatten
200
+ end
246
201
 
247
- # Atomically deletes all items from the array. This request is sent
248
- # directly to the Parse backend.
249
- # @param items [Array] items to remove
250
- def remove!(*items)
251
- return false unless @delegate.respond_to?(:op_remove!)
252
- @delegate.send :op_remove!, @key, items.flatten
253
- reset!
254
- end
202
+ # Alias {https://ruby-doc.org/core-2.4.1/Array.html#method-i-2B Array Concatenation}.
203
+ # Returns a new array built by concatenating the two arrays together to
204
+ # produce a third array.
205
+ # @example
206
+ # [ 1, 2, 3 ] + [ 4, 5 ] #=> [ 1, 2, 3, 4, 5 ]
207
+ # @param other_ary [Array]
208
+ # @return [Array] concatenated array
209
+ def +(other_ary)
210
+ collection + [other_ary].flatten.to_a
211
+ end
255
212
 
256
- # Atomically deletes all items in the array, and marks the field as `undefined` directly
257
- # with the Parse server. This request is sent directly to the Parse backend.
258
- def destroy!
259
- return false unless @delegate.respond_to?(:op_destroy!)
260
- @delegate.send :op_destroy!, @key
261
- collection_will_change!
262
- @collection.clear
263
- reset!
264
- end
213
+ # Alias {https://ruby-doc.org/core-2.4.1/Array.html#method-i-flatten Array flattening}.
214
+ # @return [Array] a flattened one-dimensional array
215
+ def flatten
216
+ collection.flatten
217
+ end
265
218
 
266
- # Locally restores previous attributes (not from the persistent store)
267
- def rollback!
268
- restore_attributes
269
- end
219
+ # Remove items from the collection
220
+ # @param items [Array] items to remove
221
+ def remove(*items)
222
+ notify_will_change! if items.count > 0
223
+ items.each do |item|
224
+ collection.delete item
225
+ end
226
+ @collection
227
+ end;
228
+ alias_method :delete, :remove
229
+
230
+ # Atomically adds all items from the array.
231
+ # This request is sent directly to the Parse backend.
232
+ # @param items [Array] items to uniquely add
233
+ # @see #add_unique!
234
+ def add!(*items)
235
+ return false unless @delegate.respond_to?(:op_add!)
236
+ @delegate.send :op_add!, @key, items.flatten
237
+ reset!
238
+ end
270
239
 
271
- # clears all dirty tracked information.
272
- def clear_changes!
273
- clear_changes_information
274
- end
240
+ # Atomically adds all items from the array that are not already part of the collection.
241
+ # This request is sent directly to the Parse backend.
242
+ # @param items [Array] items to uniquely add
243
+ # @see #add!
244
+ def add_unique!(*items)
245
+ return false unless @delegate.respond_to?(:op_add_unique!)
246
+ @delegate.send :op_add_unique!, @key, items.flatten
247
+ reset!
248
+ end
275
249
 
276
- # mark that collection changes where applied, which clears dirty tracking.
277
- def changes_applied!
278
- changes_applied
279
- end
250
+ # Atomically deletes all items from the array. This request is sent
251
+ # directly to the Parse backend.
252
+ # @param items [Array] items to remove
253
+ def remove!(*items)
254
+ return false unless @delegate.respond_to?(:op_remove!)
255
+ @delegate.send :op_remove!, @key, items.flatten
256
+ reset!
257
+ end
280
258
 
281
- # @param args [Hash] arguments to pass to Array#first.
282
- # @return [Object] the first item in the collection
283
- def first(*args)
284
- collection.first(*args)
285
- end
259
+ # Atomically deletes all items in the array, and marks the field as `undefined` directly
260
+ # with the Parse server. This request is sent directly to the Parse backend.
261
+ def destroy!
262
+ return false unless @delegate.respond_to?(:op_destroy!)
263
+ @delegate.send :op_destroy!, @key
264
+ collection_will_change!
265
+ @collection.clear
266
+ reset!
267
+ end
286
268
 
287
- # @return [Object] the second item in the collection
288
- def second
289
- collection.second
290
- end
269
+ # Locally restores previous attributes (not from the persistent store)
270
+ def rollback!
271
+ restore_attributes
272
+ end
291
273
 
292
- # @param args [Hash] arguments to pass to Array#last.
293
- # @return [Object] the last item in the collection
294
- def last(*args)
295
- collection.last(*args)
296
- end
274
+ # clears all dirty tracked information.
275
+ def clear_changes!
276
+ clear_changes_information
277
+ end
297
278
 
298
- # @return [Integer] number of items in the collection.
299
- def count
300
- collection.count
301
- end
279
+ # mark that collection changes where applied, which clears dirty tracking.
280
+ def changes_applied!
281
+ changes_applied
282
+ end
302
283
 
303
- # @return [Hash] a JSON representation
304
- def as_json(opts = nil)
305
- collection.as_json(opts)
306
- end
284
+ # @param args [Hash] arguments to pass to Array#first.
285
+ # @return [Object] the first item in the collection
286
+ def first(*args)
287
+ collection.first(*args)
288
+ end
307
289
 
308
- # true if the collection is empty.
309
- def empty?
310
- collection.empty?
311
- end
290
+ # @return [Object] the second item in the collection
291
+ def second
292
+ collection.second
293
+ end
312
294
 
313
- # Append items to the collection
314
- def <<(*list)
315
- if list.count > 0
316
- notify_will_change!
317
- list.flatten.each { |e| collection.push(e) }
318
- end
319
- end
295
+ # @param args [Hash] arguments to pass to Array#last.
296
+ # @return [Object] the last item in the collection
297
+ def last(*args)
298
+ collection.last(*args)
299
+ end
320
300
 
321
- # Notifies the delegate that the collection changed.
322
- def notify_will_change!
323
- collection_will_change!
324
- forward "#{@key}_will_change!"
325
- end
301
+ # @return [Integer] number of items in the collection.
302
+ def count
303
+ collection.count
304
+ end
326
305
 
327
- # Alias for Array#each
328
- def each
329
- return collection.enum_for(:each) unless block_given?
330
- collection.each &Proc.new
331
- end
306
+ # @return [Hash] a JSON representation
307
+ def as_json(opts = nil)
308
+ collection.as_json(opts)
309
+ end
332
310
 
333
- # Alias for Array#map
334
- def map
335
- return collection.enum_for(:map) unless block_given?
336
- collection.map &Proc.new
337
- end
311
+ # true if the collection is empty.
312
+ def empty?
313
+ collection.empty?
314
+ end
338
315
 
339
- # Alias for Array#select
340
- def select
341
- return collection.enum_for(:select) unless block_given?
342
- collection.select &Proc.new
316
+ # Append items to the collection
317
+ def <<(*list)
318
+ if list.count > 0
319
+ notify_will_change!
320
+ list.flatten.each { |e| collection.push(e) }
343
321
  end
322
+ end
344
323
 
345
- # Alias for Array#uniq
346
- def uniq
347
- return collection.uniq(&Proc.new) if block_given?
348
- return collection.uniq
349
- end
324
+ # Notifies the delegate that the collection changed.
325
+ def notify_will_change!
326
+ collection_will_change!
327
+ forward "#{@key}_will_change!"
328
+ end
350
329
 
351
- # Alias for Array#uniq!
352
- def uniq!
353
- notify_will_change!
354
- return collection.uniq!(&Proc.new) if block_given?
355
- return collection.uniq!
356
- end
330
+ # Alias for Array#each
331
+ def each
332
+ return collection.enum_for(:each) unless block_given?
333
+ collection.each &Proc.new
334
+ end
357
335
 
358
- # @!visibility private
359
- def inspect
360
- "#<#{self.class} changed?=#{changed?} @collection=#{@collection.inspect} >"
361
- end
336
+ # Alias for Array#map
337
+ def map
338
+ return collection.enum_for(:map) unless block_given?
339
+ collection.map &Proc.new
340
+ end
362
341
 
363
- # Alias to `to_a.parse_objects` from Array#parse_objects
364
- # @return [Array<Parse::Object>] an array of Parse Object subclasses representing this collection.
365
- def parse_objects
366
- collection.to_a.parse_objects
367
- end
342
+ # Alias for Array#select
343
+ def select
344
+ return collection.enum_for(:select) unless block_given?
345
+ collection.select &Proc.new
346
+ end
368
347
 
369
- # Alias to `to_a.parse_pointers` from Array#parse_pointers
370
- # @return [Array<Parse::Pointer>] an array of pointers representing this collection.
371
- def parse_pointers
372
- collection.to_a.parse_pointers
373
- end
348
+ # Alias for Array#uniq
349
+ def uniq
350
+ return collection.uniq(&Proc.new) if block_given?
351
+ return collection.uniq
352
+ end
374
353
 
354
+ # Alias for Array#uniq!
355
+ def uniq!
356
+ notify_will_change!
357
+ return collection.uniq!(&Proc.new) if block_given?
358
+ return collection.uniq!
375
359
  end
376
360
 
361
+ # @!visibility private
362
+ def inspect
363
+ "#<#{self.class} changed?=#{changed?} @collection=#{@collection.inspect} >"
364
+ end
377
365
 
366
+ # Alias to `to_a.parse_objects` from Array#parse_objects
367
+ # @return [Array<Parse::Object>] an array of Parse Object subclasses representing this collection.
368
+ def parse_objects
369
+ collection.to_a.parse_objects
370
+ end
378
371
 
372
+ # Alias to `to_a.parse_pointers` from Array#parse_pointers
373
+ # @return [Array<Parse::Pointer>] an array of pointers representing this collection.
374
+ def parse_pointers
375
+ collection.to_a.parse_pointers
376
+ end
379
377
  end
378
+ end