parse-stack 1.8.0 → 1.8.1

Sign up to get free protection for your applications and to get access to all the features.
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