parse-stack 1.5.1 → 1.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changes.md +15 -1
- data/Gemfile.lock +10 -10
- data/README.md +23 -9
- data/bin/console +3 -0
- data/lib/parse/api/analytics.rb +1 -1
- data/lib/parse/api/objects.rb +1 -1
- data/lib/parse/api/users.rb +1 -1
- data/lib/parse/client.rb +77 -40
- data/lib/parse/client/caching.rb +9 -5
- data/lib/parse/client/protocol.rb +47 -0
- data/lib/parse/client/request.rb +66 -37
- data/lib/parse/client/response.rb +39 -21
- data/lib/parse/model/acl.rb +4 -9
- data/lib/parse/model/associations/belongs_to.rb +97 -9
- data/lib/parse/model/associations/collection_proxy.rb +89 -29
- data/lib/parse/model/associations/has_many.rb +301 -28
- data/lib/parse/model/associations/has_one.rb +98 -4
- data/lib/parse/model/associations/pointer_collection_proxy.rb +48 -16
- data/lib/parse/model/associations/relation_collection_proxy.rb +61 -36
- data/lib/parse/model/bytes.rb +11 -5
- data/lib/parse/model/classes/installation.rb +50 -3
- data/lib/parse/model/classes/role.rb +7 -2
- data/lib/parse/model/classes/session.rb +21 -4
- data/lib/parse/model/classes/user.rb +122 -22
- data/lib/parse/model/core/actions.rb +7 -3
- data/lib/parse/model/core/properties.rb +14 -13
- data/lib/parse/model/core/querying.rb +16 -10
- data/lib/parse/model/core/schema.rb +2 -3
- data/lib/parse/model/date.rb +18 -12
- data/lib/parse/model/file.rb +77 -19
- data/lib/parse/model/geopoint.rb +70 -12
- data/lib/parse/model/model.rb +84 -8
- data/lib/parse/model/object.rb +225 -94
- data/lib/parse/model/pointer.rb +94 -13
- data/lib/parse/model/push.rb +76 -4
- data/lib/parse/query.rb +356 -41
- data/lib/parse/query/constraints.rb +399 -29
- data/lib/parse/query/ordering.rb +21 -8
- data/lib/parse/stack.rb +1 -0
- data/lib/parse/stack/version.rb +2 -1
- data/lib/parse/webhooks.rb +0 -24
- data/lib/parse/webhooks/payload.rb +54 -1
- data/lib/parse/webhooks/registration.rb +13 -2
- metadata +2 -2
data/lib/parse/model/object.rb
CHANGED
@@ -30,65 +30,62 @@ require_relative "associations/has_many"
|
|
30
30
|
|
31
31
|
|
32
32
|
module Parse
|
33
|
-
|
34
|
-
This is the core class for all app specific Parse table subclasses. This class
|
35
|
-
in herits from Parse::Pointer since an Object is a Parse::Pointer with additional fields,
|
36
|
-
at a minimum, created_at, updated_at and ACLs.
|
37
|
-
This class also handles all the relational types of associations in a Parse application and
|
38
|
-
handles the main CRUD operations.
|
39
|
-
|
40
|
-
Most Pointers and Object subclasses are treated the same. Therefore, defining a class Artist < Parse::Object
|
41
|
-
that only has `id` set, will be treated as a pointer. Therefore a Parse::Object can be in a "pointer" state
|
42
|
-
based on the data that it contains. Becasue of this, it is possible to take a Artist instance
|
43
|
-
(in this example), that is in a pointer state, and fetch the rest of the data for that particular
|
44
|
-
record without having to create a new object. Doing so would now mark it as not being a pointer anymore.
|
45
|
-
This is important to the understanding on how relations and properties are handled.
|
46
|
-
|
47
|
-
The implementation of this class is large and has been broken up into several modules.
|
48
|
-
|
49
|
-
Properties:
|
50
|
-
All columns in a Parse object are considered a type of property (ex. string, numbers, arrays, etc)
|
51
|
-
except in two cases - Pointers and Relations. For the list of basic supported data types, please see the
|
52
|
-
Properties module variable Parse::Properties::TYPES . When defining a property,
|
53
|
-
dynamic methods are created that take advantage of all the ActiveModel
|
54
|
-
plugins (dirty tracking, callbacks, json, etc).
|
55
|
-
|
56
|
-
Associations (BelongsTo):
|
57
|
-
This module adds support for creating an association between one object to another using a
|
58
|
-
Parse object pointer. By defining a belongs_to relationship in a specific class, it implies
|
59
|
-
that the remote Parse table contains a local column, which has a pointer, referring to another
|
60
|
-
Parse table.
|
61
|
-
|
62
|
-
Associations (HasMany):
|
63
|
-
In Parse there are two ways to deal with one-to-many and many-to-many relationships
|
64
|
-
One is through an array of pointers (which is recommended to be less than 100) and
|
65
|
-
through an intermediary table called a Relation (or a Join table in other languages.)
|
66
|
-
The way Parse::Objects treat these associations different from defining a :property of array type, is
|
67
|
-
by making sure items in the array as of a particular class cast type.
|
68
|
-
|
69
|
-
Querying:
|
70
|
-
The querying module provides all the general methods to be able to find and query a specific
|
71
|
-
Parse table.
|
72
|
-
|
73
|
-
Fetching:
|
74
|
-
The fetching modules supports fetching data from Parse (depending on the state of the object),
|
75
|
-
and providing some autofetching features when traversing relational objects and properties.
|
76
|
-
|
77
|
-
Schema:
|
78
|
-
The schema module provides methods to modify the Parse table remotely to either add or create
|
79
|
-
any locally define properties in ruby and have those be reflected in the Parse application.
|
80
|
-
|
81
|
-
=end
|
82
|
-
|
33
|
+
# @return [Array] an array of registered Parse::Object subclasses.
|
83
34
|
def self.registered_classes
|
84
35
|
Parse::Object.descendants.map { |m| m.parse_class }.uniq
|
85
36
|
end
|
86
37
|
|
87
|
-
#
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
38
|
+
# This is the core class for all app specific Parse table subclasses. This class
|
39
|
+
# in herits from Parse::Pointer since an Object is a Parse::Pointer with additional fields,
|
40
|
+
# at a minimum, created_at, updated_at and ACLs.
|
41
|
+
# This class also handles all the relational types of associations in a Parse application and
|
42
|
+
# handles the main CRUD operations.
|
43
|
+
#
|
44
|
+
# Most Pointers and Object subclasses are treated the same. Therefore, defining a class Artist < Parse::Object
|
45
|
+
# that only has `id` set, will be treated as a pointer. Therefore a Parse::Object can be in a "pointer" state
|
46
|
+
# based on the data that it contains. Becasue of this, it is possible to take a Artist instance
|
47
|
+
# (in this example), that is in a pointer state, and fetch the rest of the data for that particular
|
48
|
+
# record without having to create a new object. Doing so would now mark it as not being a pointer anymore.
|
49
|
+
# This is important to the understanding on how relations and properties are handled.
|
50
|
+
#
|
51
|
+
# The implementation of this class is large and has been broken up into several modules.
|
52
|
+
#
|
53
|
+
# Properties:
|
54
|
+
#
|
55
|
+
# All columns in a Parse object are considered a type of property (ex. string, numbers, arrays, etc)
|
56
|
+
# except in two cases - Pointers and Relations. For the list of basic supported data types, please see the
|
57
|
+
# Properties module variable Parse::Properties::TYPES . When defining a property,
|
58
|
+
# dynamic methods are created that take advantage of all the ActiveModel
|
59
|
+
# plugins (dirty tracking, callbacks, json, etc).
|
60
|
+
#
|
61
|
+
# Associations:
|
62
|
+
#
|
63
|
+
# Parse supports a three main types of relational associations. One type of
|
64
|
+
# relation is the `One-to-One` association. This is implemented through a
|
65
|
+
# specific column in Parse with a Pointer data type. This pointer column,
|
66
|
+
# contains a local value that refers to a different record in a separate Parse
|
67
|
+
# table. This association is implemented using the `:belongs_to` feature. The
|
68
|
+
# second association is of `One-to-Many`. This is implemented is in Parse as a
|
69
|
+
# Array type column that contains a list of of Parse pointer objects. It is
|
70
|
+
# recommended by Parse that this array does not exceed 100 items for performance
|
71
|
+
# reasons. This feature is implemented using the `:has_many` operation with the
|
72
|
+
# plural name of the local Parse class. The last association type is a Parse
|
73
|
+
# Relation. These can be used to implement a large `Many-to-Many` association
|
74
|
+
# without requiring an explicit intermediary Parse table or class. This feature
|
75
|
+
# is also implemented using the `:has_many` method but passing the option of `:relation`.
|
76
|
+
#
|
77
|
+
#
|
78
|
+
# Querying:
|
79
|
+
# The querying module provides all the general methods to be able to find and query a specific
|
80
|
+
# Parse table.
|
81
|
+
#
|
82
|
+
# Fetching:
|
83
|
+
# The fetching modules supports fetching data from Parse (depending on the state of the object),
|
84
|
+
# and providing some autofetching features when traversing relational objects and properties.
|
85
|
+
#
|
86
|
+
# Schema:
|
87
|
+
# The schema module provides methods to modify the Parse table remotely to either add or create
|
88
|
+
# any locally define properties in ruby and have those be reflected in the Parse application.
|
92
89
|
class Object < Pointer
|
93
90
|
include Properties
|
94
91
|
include Associations::HasOne
|
@@ -98,14 +95,45 @@ module Parse
|
|
98
95
|
include Fetching
|
99
96
|
include Actions
|
100
97
|
include Schema
|
101
|
-
BASE_OBJECT_CLASS = "Parse::Object".freeze
|
98
|
+
BASE_OBJECT_CLASS = "Parse::Object".freeze
|
102
99
|
|
100
|
+
# @return [Model::TYPE_OBJECT]
|
103
101
|
def __type; Parse::Model::TYPE_OBJECT; end;
|
104
|
-
|
102
|
+
|
103
|
+
# Default ActiveModel::Callbacks
|
104
|
+
# @!group Callbacks
|
105
|
+
#
|
106
|
+
# @!method before_create
|
107
|
+
# A callback called before the object has been created.
|
108
|
+
# @yield A block to execute for the callback.
|
109
|
+
# @see ActiveModel::Callbacks
|
110
|
+
# @!method after_create
|
111
|
+
# A callback called after the object has been created.
|
112
|
+
# @yield A block to execute for the callback.
|
113
|
+
# @see ActiveModel::Callbacks
|
114
|
+
# @!method before_save
|
115
|
+
# A callback called before the object is saved.
|
116
|
+
# @note This is not related to a Parse beforeSave webhook trigger.
|
117
|
+
# @yield A block to execute for the callback.
|
118
|
+
# @see ActiveModel::Callbacks
|
119
|
+
# @!method after_save
|
120
|
+
# A callback called after the object has been successfully saved.
|
121
|
+
# @note This is not related to a Parse afterSave webhook trigger.
|
122
|
+
# @yield A block to execute for the callback.
|
123
|
+
# @see ActiveModel::Callbacks
|
124
|
+
# @!method before_destroy
|
125
|
+
# A callback called before the object is about to be deleted.
|
126
|
+
# @note This is not related to a Parse beforeDelete webhook trigger.
|
127
|
+
# @yield A block to execute for the callback.
|
128
|
+
# @see ActiveModel::Callbacks
|
129
|
+
# @!method after_destroy
|
130
|
+
# A callback called after the object has been successfully deleted.
|
131
|
+
# @note This is not related to a Parse afterDelete webhook trigger.
|
132
|
+
# @yield A block to execute for the callback.
|
133
|
+
# @see ActiveModel::Callbacks
|
134
|
+
# @!endgroup
|
105
135
|
define_model_callbacks :create, :save, :destroy, only: [:after, :before]
|
106
|
-
|
107
|
-
# setters are available since we will be decoding objects from Parse. The :acl
|
108
|
-
# type is documented in its own class file.
|
136
|
+
|
109
137
|
attr_accessor :created_at, :updated_at, :acl
|
110
138
|
|
111
139
|
# All Parse Objects have a class-level and instance level `parse_class` method, in which the
|
@@ -114,17 +142,41 @@ module Parse
|
|
114
142
|
# the remote Parse table is named 'Artist'. You may override this behavior by utilizing the `parse_class(<className>)` method
|
115
143
|
# to set it to something different.
|
116
144
|
class << self
|
117
|
-
|
118
|
-
attr_accessor :parse_class, :acl
|
119
|
-
|
145
|
+
|
146
|
+
attr_accessor :disable_serialized_string_date, :parse_class, :acl
|
147
|
+
|
148
|
+
# @!attribute [rw] disable_serialized_string_date
|
149
|
+
# Disables returning a serialized string date properties when encoding to JSON.
|
150
|
+
# This affects created_at and updated_at fields in order to be backwards compatible with old SDKs.
|
151
|
+
# @return [Boolean]
|
152
|
+
|
153
|
+
# The class method to override the implicitly assumed Parse collection name
|
154
|
+
# in your Parse database. The default Parse collection name is the singular form
|
155
|
+
# of the ruby Parse::Object subclass name. The Parse class value should match to
|
156
|
+
# the corresponding remote table in your database in order to properly store records and
|
157
|
+
# perform queries.
|
158
|
+
# @example
|
159
|
+
# class Song < Parse::Object; end;
|
160
|
+
# class Artist < Parse::Object
|
161
|
+
# parse_class "Musician" # remote collection name
|
162
|
+
# end
|
163
|
+
#
|
164
|
+
# Parse::User.parse_class # => '_User'
|
165
|
+
# Song.parse_class # => 'Song'
|
166
|
+
# Artist.parse_class # => 'Musician'
|
167
|
+
#
|
168
|
+
# @param remoteName [String] the name of the remote collection
|
169
|
+
# @return [String] the name of the Parse collection for this model.
|
170
|
+
def parse_class(remoteName = nil)
|
120
171
|
@parse_class ||= model_name.name
|
121
|
-
unless
|
122
|
-
@parse_class = c.to_s
|
123
|
-
end
|
172
|
+
@parse_class = remoteName.to_s unless remoteName.nil?
|
124
173
|
@parse_class
|
125
174
|
end
|
126
|
-
|
127
|
-
|
175
|
+
|
176
|
+
# A method to override the default ACLs for new objects for this particular
|
177
|
+
# subclass.
|
178
|
+
# @param acls [Hash] a hash with key value pairs of ACLs permissions.
|
179
|
+
# @return [ACL] the default ACLs for this class.
|
128
180
|
def acl(acls = {}, owner: nil)
|
129
181
|
acls = {"*" => {read: true, write: false} }.merge( acls ).symbolize_keys
|
130
182
|
@acl ||= Parse::ACL.new(acls, owner: owner)
|
@@ -132,15 +184,39 @@ module Parse
|
|
132
184
|
|
133
185
|
end
|
134
186
|
|
187
|
+
# @return [String] the Parse class for this object.
|
188
|
+
# @see Parse::Object.parse_class
|
135
189
|
def parse_class
|
136
190
|
self.class.parse_class
|
137
191
|
end
|
138
192
|
alias_method :className, :parse_class
|
139
193
|
|
194
|
+
# @return [Hash] a json-hash representing this object.
|
140
195
|
def as_json(*args)
|
141
196
|
pointer? ? pointer : super(*args)
|
142
197
|
end
|
143
198
|
|
199
|
+
# The main constructor for subclasses. It can take different parameter types
|
200
|
+
# including a String and a JSON hash. Assume a `Post` class that inherits
|
201
|
+
# from Parse::Object:
|
202
|
+
# @note Should only be called with Parse::Object subclasses.
|
203
|
+
# @overload new(id)
|
204
|
+
# Create a new object with an objectId. This method is useful for creating
|
205
|
+
# an unfetched object (pointer-state).
|
206
|
+
# @example
|
207
|
+
# Post.new "1234"
|
208
|
+
# @param id [String] The object id.
|
209
|
+
# @overload new(hash = {})
|
210
|
+
# Create a new object with Parse JSON hash.
|
211
|
+
# @example
|
212
|
+
# # JSON hash from Parse
|
213
|
+
# Post.new({"className" => "Post", "objectId" => "1234", "title" => "My Title"})
|
214
|
+
#
|
215
|
+
# post = Post.new title: "My Title"
|
216
|
+
# post.title # => "My Title"
|
217
|
+
#
|
218
|
+
# @param hash [Hash] the hash representing the object
|
219
|
+
# @return [Parse::Object] a the corresponding Parse::Object or subclass.
|
144
220
|
def initialize(opts = {})
|
145
221
|
if opts.is_a?(String) #then it's the objectId
|
146
222
|
@id = opts.to_s
|
@@ -162,28 +238,36 @@ module Parse
|
|
162
238
|
# do not call super since it is Pointer subclass
|
163
239
|
end
|
164
240
|
|
241
|
+
# force apply default values for any properties defined with default values.
|
242
|
+
# @return [Array] list of default fields
|
165
243
|
def apply_defaults!
|
166
244
|
self.class.defaults_list.each do |key|
|
167
245
|
send(key) # should call set default proc/values if nil
|
168
246
|
end
|
169
247
|
end
|
170
248
|
|
249
|
+
# Helper method to create a Parse::Pointer object for a given id.
|
250
|
+
# @param id [String] The objectId
|
251
|
+
# @return [Parse::Pointer] a pointer object corresponding to this class and id.
|
171
252
|
def self.pointer(id)
|
172
253
|
return nil if id.nil?
|
173
254
|
Parse::Pointer.new self.parse_class, id
|
174
255
|
end
|
175
256
|
|
176
|
-
#
|
177
|
-
# pending changes, then it is considered to not yet be persisted.
|
178
|
-
#
|
257
|
+
# Determines if this object has been saved to the Parse database. If an object has
|
258
|
+
# pending changes, then it is considered to not yet be persisted.
|
259
|
+
# @return [Boolean] true if this object has not been saved.
|
179
260
|
def persisted?
|
180
261
|
changed? == false && !(@id.nil? || @created_at.nil? || @updated_at.nil? || @acl.nil?)
|
181
262
|
end
|
182
263
|
|
183
|
-
# force reload and replace any local fields with data from
|
184
|
-
|
264
|
+
# force reload from the database and replace any local fields with data from
|
265
|
+
# the persistent store
|
266
|
+
# @param opts [Hash] a set of options to send to fetch!
|
267
|
+
# @see Fetching#fetch!
|
268
|
+
def reload!(opts = {})
|
185
269
|
# get the values from the persistence layer
|
186
|
-
fetch!
|
270
|
+
fetch!(opts)
|
187
271
|
clear_changes!
|
188
272
|
end
|
189
273
|
|
@@ -192,13 +276,20 @@ module Parse
|
|
192
276
|
clear_changes_information
|
193
277
|
end
|
194
278
|
|
195
|
-
#
|
279
|
+
# An object is considered new if it has no id. This is the method to use
|
280
|
+
# in a webhook beforeSave when checking if this object is new.
|
281
|
+
# @return [Boolean] true if the object has no id.
|
196
282
|
def new?
|
197
283
|
@id.blank?
|
198
284
|
end
|
199
285
|
|
200
286
|
# Existed returns true/false depending whether the object
|
201
|
-
# had existed before its last save operation
|
287
|
+
# had existed before *its last save operation*. This implies
|
288
|
+
# that the created_at and updated_at dates are exactly the same. This
|
289
|
+
# is a helper method in a webhook afterSave to know if this object was recently
|
290
|
+
# saved in the beforeSave webhook.
|
291
|
+
# @note You should not use this method inside a beforeSave webhook.
|
292
|
+
# @return [Boolean] true if the last beforeSave webhook successfully saved this object for the first time.
|
202
293
|
def existed?
|
203
294
|
if @id.blank? || @created_at.blank? || @updated_at.blank?
|
204
295
|
return false
|
@@ -206,9 +297,12 @@ module Parse
|
|
206
297
|
created_at != updated_at
|
207
298
|
end
|
208
299
|
|
209
|
-
#
|
300
|
+
# Returns a hash of all the changes that have been made to the object. By default
|
210
301
|
# changes to the Parse::Properties::BASE_KEYS are ignored unless you pass true as
|
211
302
|
# an argument.
|
303
|
+
# @param include_all [Boolean] whether to include all keys in result.
|
304
|
+
# @return [Hash] a hash containing only the change information.
|
305
|
+
# @see Properties::BASE_KEYS
|
212
306
|
def updates(include_all = false)
|
213
307
|
h = {}
|
214
308
|
changed.each do |key|
|
@@ -223,20 +317,29 @@ module Parse
|
|
223
317
|
h
|
224
318
|
end
|
225
319
|
|
226
|
-
# restores the previous state of the object
|
320
|
+
# Locally restores the previous state of the object and clears all dirty
|
321
|
+
# tracking information.
|
322
|
+
# @note This does not reload the object from the persistent store, for this use "reload!" instead.
|
323
|
+
# @see #reload!
|
227
324
|
def rollback!
|
228
325
|
restore_attributes
|
229
326
|
end
|
230
327
|
|
231
|
-
#
|
232
|
-
#
|
233
|
-
# otherwise
|
328
|
+
# Overrides ActiveModel::Validations#validate! instance method.
|
329
|
+
# It runs all valudations for this object. If it validation fails,
|
330
|
+
# it raises ActiveModel::ValidationError otherwise it returns the object.
|
331
|
+
# @raise ActiveModel::ValidationError
|
332
|
+
# @see ActiveModel::Validations#validate!
|
333
|
+
# @return [self] self the object if validation passes.
|
234
334
|
def validate!
|
235
335
|
super
|
236
336
|
self
|
237
337
|
end
|
238
338
|
|
239
|
-
#
|
339
|
+
# This method creates a new object of the same instance type with a copy of
|
340
|
+
# all the properties of the current instance. This is useful when you want
|
341
|
+
# to create a duplicate record.
|
342
|
+
# @return [Parse::Object] a twin copy of the object without the objectId
|
240
343
|
def twin
|
241
344
|
h = self.as_json
|
242
345
|
h.delete(Parse::Model::OBJECT_ID)
|
@@ -245,10 +348,13 @@ module Parse
|
|
245
348
|
self.class.new h
|
246
349
|
end
|
247
350
|
|
351
|
+
# @return [String] a pretty-formatted JSON string
|
352
|
+
# @see JSON.pretty_generate
|
248
353
|
def pretty
|
249
354
|
JSON.pretty_generate( as_json )
|
250
355
|
end
|
251
356
|
|
357
|
+
# clear all change and dirty tracking information.
|
252
358
|
def clear_attribute_change!(atts)
|
253
359
|
clear_attribute_changes(atts)
|
254
360
|
end
|
@@ -256,9 +362,22 @@ module Parse
|
|
256
362
|
# Method used for decoding JSON objects into their corresponding Object subclasses.
|
257
363
|
# The first parameter is a hash containing the object data and the second parameter is the
|
258
364
|
# name of the table / class if it is known. If it is not known, we we try and determine it
|
259
|
-
# by checking the "className" or :className entries in the hash.
|
260
|
-
# is encoutered for which we don't have a
|
261
|
-
# will be returned instead.
|
365
|
+
# by checking the "className" or :className entries in the hash.
|
366
|
+
# @note If a Parse class object hash is encoutered for which we don't have a
|
367
|
+
# corresponding Parse::Object subclass for, a Parse::Pointer will be returned instead.
|
368
|
+
#
|
369
|
+
# @example
|
370
|
+
# # assume you have defined Post subclass
|
371
|
+
# post = Parse::Object.build({"className" => "Post", "objectId" => '1234'})
|
372
|
+
# post # => #<Post:....>
|
373
|
+
#
|
374
|
+
# # if you know the table name
|
375
|
+
# post = Parse::Object.build({"title" => "My Title"}, "Post")
|
376
|
+
# # or
|
377
|
+
# post = Post.build({"title" => "My Title"})
|
378
|
+
# @param json [Hash] a JSON hash that contains a Parse object.
|
379
|
+
# @param table [String] the Parse class for this hash. If not passed it will be detected.
|
380
|
+
# @return [Parse::Object] an instance of the Parse subclass
|
262
381
|
def self.build(json, table = nil)
|
263
382
|
className = table
|
264
383
|
className ||= (json[Parse::Model::KEY_CLASS_NAME] || json[:className]) if json.is_a?(Hash)
|
@@ -285,14 +404,22 @@ module Parse
|
|
285
404
|
# puts "Parse::Object.build error: #{e}"
|
286
405
|
end
|
287
406
|
|
288
|
-
#
|
407
|
+
# @!attribute [rw] id
|
408
|
+
# @return [String] the value of Parse "objectId" field.
|
409
|
+
|
410
|
+
# @!attribute [r] created_at
|
411
|
+
# @return [Date] the created_at date of the record in UTC Zulu iso 8601 with 3 millisecond format.
|
412
|
+
|
413
|
+
# @!attribute [r] updated_at
|
414
|
+
# @return [Date] the updated_at date of the record in UTC Zulu iso 8601 with 3 millisecond format.
|
415
|
+
|
416
|
+
# @!attribute [rw] acl
|
417
|
+
# @return [ACL] the access control list (permissions) object for this record.
|
289
418
|
property :id, field: :objectId
|
290
419
|
property :created_at, :date
|
291
420
|
property :updated_at, :date
|
292
421
|
property :acl, :acl, field: :ACL
|
293
422
|
|
294
|
-
# TODO: Hack since Parse createdAt and updatedAt dates have to be returned as strings
|
295
|
-
# in UTC Zulu iso 8601 with 3 millisecond format.
|
296
423
|
def createdAt
|
297
424
|
return @created_at if Parse::Object.disable_serialized_string_date.present?
|
298
425
|
@created_at.to_time.utc.iso8601(3) if @created_at.present?
|
@@ -305,24 +432,28 @@ module Parse
|
|
305
432
|
|
306
433
|
end
|
307
434
|
|
435
|
+
|
308
436
|
end
|
309
437
|
|
310
438
|
class Array
|
311
|
-
# This helper method selects all objects in an array that are either inherit from
|
312
|
-
# Parse::Pointer or are a hash. If it is a hash, a Pare::Object will be built from it
|
313
|
-
# if it constains the proper fields. Non
|
439
|
+
# This helper method selects or converts all objects in an array that are either inherit from
|
440
|
+
# Parse::Pointer or are a JSON Parse hash. If it is a hash, a Pare::Object will be built from it
|
441
|
+
# if it constains the proper fields. Non-convertible objects will be removed.
|
314
442
|
# If the className is not contained or known, you can pass a table name as an argument
|
315
|
-
|
443
|
+
# @param className [String] the name of the Parse class if it could not be detected.
|
444
|
+
# @return [Array<Parse::Object>] an array of Parse::Object subclasses.
|
445
|
+
def parse_objects(className = nil)
|
316
446
|
f = Parse::Model::KEY_CLASS_NAME
|
317
447
|
map do |m|
|
318
448
|
next m if m.is_a?(Parse::Pointer)
|
319
|
-
if m.is_a?(Hash) && (m[f] || m[:className] ||
|
320
|
-
next Parse::Object.build m, (m[f] || m[:className] ||
|
449
|
+
if m.is_a?(Hash) && (m[f] || m[:className] || className)
|
450
|
+
next Parse::Object.build m, (m[f] || m[:className] || className)
|
321
451
|
end
|
322
452
|
nil
|
323
453
|
end.compact
|
324
454
|
end
|
325
455
|
|
456
|
+
# @return [Array<String>] an array of objectIds for all objects that are Parse::Objects.
|
326
457
|
def parse_ids
|
327
458
|
parse_objects.map(&:id)
|
328
459
|
end
|