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.
- checksums.yaml +4 -4
- data/.solargraph.yml +23 -0
- data/.travis.yml +0 -1
- data/Gemfile +13 -12
- data/Gemfile.lock +88 -51
- data/README.md +2 -4
- data/Rakefile +14 -14
- data/lib/parse/api/aggregate.rb +4 -7
- data/lib/parse/api/all.rb +1 -1
- data/lib/parse/api/analytics.rb +0 -3
- data/lib/parse/api/batch.rb +3 -5
- data/lib/parse/api/cloud_functions.rb +0 -3
- data/lib/parse/api/config.rb +0 -4
- data/lib/parse/api/files.rb +3 -7
- data/lib/parse/api/hooks.rb +4 -8
- data/lib/parse/api/objects.rb +7 -12
- data/lib/parse/api/push.rb +0 -4
- data/lib/parse/api/schema.rb +2 -6
- data/lib/parse/api/server.rb +4 -7
- data/lib/parse/api/sessions.rb +2 -5
- data/lib/parse/api/users.rb +9 -14
- data/lib/parse/client.rb +54 -50
- data/lib/parse/client/authentication.rb +29 -33
- data/lib/parse/client/batch.rb +8 -11
- data/lib/parse/client/body_builder.rb +19 -20
- data/lib/parse/client/caching.rb +23 -28
- data/lib/parse/client/protocol.rb +11 -12
- data/lib/parse/client/request.rb +4 -6
- data/lib/parse/client/response.rb +5 -7
- data/lib/parse/model/acl.rb +14 -12
- data/lib/parse/model/associations/belongs_to.rb +14 -21
- data/lib/parse/model/associations/collection_proxy.rb +328 -329
- data/lib/parse/model/associations/has_many.rb +18 -25
- data/lib/parse/model/associations/has_one.rb +6 -11
- data/lib/parse/model/associations/pointer_collection_proxy.rb +5 -8
- data/lib/parse/model/associations/relation_collection_proxy.rb +5 -9
- data/lib/parse/model/bytes.rb +8 -10
- data/lib/parse/model/classes/installation.rb +2 -4
- data/lib/parse/model/classes/product.rb +2 -5
- data/lib/parse/model/classes/role.rb +3 -5
- data/lib/parse/model/classes/session.rb +2 -5
- data/lib/parse/model/classes/user.rb +20 -16
- data/lib/parse/model/core/actions.rb +31 -46
- data/lib/parse/model/core/builder.rb +6 -6
- data/lib/parse/model/core/errors.rb +0 -1
- data/lib/parse/model/core/fetching.rb +45 -50
- data/lib/parse/model/core/properties.rb +51 -66
- data/lib/parse/model/core/querying.rb +291 -294
- data/lib/parse/model/core/schema.rb +89 -92
- data/lib/parse/model/date.rb +16 -17
- data/lib/parse/model/file.rb +171 -174
- data/lib/parse/model/geopoint.rb +12 -16
- data/lib/parse/model/model.rb +31 -37
- data/lib/parse/model/object.rb +47 -53
- data/lib/parse/model/pointer.rb +177 -176
- data/lib/parse/model/push.rb +8 -10
- data/lib/parse/model/shortnames.rb +1 -2
- data/lib/parse/model/time_zone.rb +3 -5
- data/lib/parse/query.rb +34 -35
- data/lib/parse/query/constraint.rb +4 -6
- data/lib/parse/query/constraints.rb +21 -29
- data/lib/parse/query/operation.rb +8 -11
- data/lib/parse/query/ordering.rb +45 -49
- data/lib/parse/stack.rb +11 -12
- data/lib/parse/stack/generators/rails.rb +28 -30
- data/lib/parse/stack/generators/templates/model.erb +5 -6
- data/lib/parse/stack/generators/templates/model_installation.rb +0 -1
- data/lib/parse/stack/generators/templates/model_role.rb +0 -1
- data/lib/parse/stack/generators/templates/model_session.rb +0 -1
- data/lib/parse/stack/generators/templates/model_user.rb +0 -1
- data/lib/parse/stack/generators/templates/parse.rb +9 -9
- data/lib/parse/stack/generators/templates/webhooks.rb +1 -2
- data/lib/parse/stack/railtie.rb +2 -4
- data/lib/parse/stack/tasks.rb +70 -86
- data/lib/parse/stack/version.rb +1 -1
- data/lib/parse/webhooks.rb +19 -26
- data/lib/parse/webhooks/payload.rb +26 -28
- data/lib/parse/webhooks/registration.rb +23 -31
- data/parse-stack.gemspec +25 -25
- data/parse-stack.png +0 -0
- metadata +13 -7
- data/.github/parse-ruby-sdk.png +0 -0
data/lib/parse/model/geopoint.rb
CHANGED
@@ -24,7 +24,7 @@ module Parse
|
|
24
24
|
#
|
25
25
|
class GeoPoint < Model
|
26
26
|
# The default attributes in a Parse GeoPoint hash.
|
27
|
-
ATTRIBUTES = {
|
27
|
+
ATTRIBUTES = { __type: :string, latitude: :float, longitude: :float }.freeze
|
28
28
|
|
29
29
|
# @return [Float] latitude value between -90.0 and 90.0
|
30
30
|
attr_accessor :latitude
|
@@ -47,9 +47,10 @@ module Parse
|
|
47
47
|
alias_method :lat, :latitude
|
48
48
|
alias_method :lng, :longitude
|
49
49
|
# @return [Model::TYPE_GEOPOINT]
|
50
|
-
def self.parse_class; TYPE_GEOPOINT; end
|
50
|
+
def self.parse_class; TYPE_GEOPOINT; end
|
51
51
|
# @return [Model::TYPE_GEOPOINT]
|
52
|
-
def parse_class; self.class.parse_class; end
|
52
|
+
def parse_class; self.class.parse_class; end
|
53
|
+
|
53
54
|
alias_method :__type, :parse_class
|
54
55
|
|
55
56
|
# The initializer can create a GeoPoint with a hash, array or values.
|
@@ -77,7 +78,6 @@ module Parse
|
|
77
78
|
|
78
79
|
# @!visibility private
|
79
80
|
def _validate_point
|
80
|
-
|
81
81
|
unless @latitude.nil? || @latitude.between?(LAT_MIN, LAT_MAX)
|
82
82
|
warn "[Parse::GeoPoint] Latitude (#{@latitude}) is not between #{LAT_MIN}, #{LAT_MAX}!"
|
83
83
|
warn "Attempting to use GeoPoint’s with latitudes outside these ranges will raise an exception in a future release."
|
@@ -87,7 +87,6 @@ module Parse
|
|
87
87
|
warn "[Parse::GeoPoint] Longitude (#{@longitude}) is not between #{LNG_MIN}, #{LNG_MAX}!"
|
88
88
|
warn "Attempting to use GeoPoint’s with longitude outside these ranges will raise an exception in a future release."
|
89
89
|
end
|
90
|
-
|
91
90
|
end
|
92
91
|
|
93
92
|
# @return [Hash] attributes for a Parse GeoPoint.
|
@@ -99,7 +98,7 @@ module Parse
|
|
99
98
|
# @return [Array] containing [lat,lng,miles]
|
100
99
|
def max_miles(m)
|
101
100
|
m = 0 if m.nil?
|
102
|
-
[@latitude
|
101
|
+
[@latitude, @longitude, m]
|
103
102
|
end
|
104
103
|
|
105
104
|
def latitude=(l)
|
@@ -118,7 +117,7 @@ module Parse
|
|
118
117
|
if h.is_a?(Hash)
|
119
118
|
h = h.symbolize_keys
|
120
119
|
@latitude = h[:latitude].to_f || h[:lat].to_f || @latitude
|
121
|
-
@longitude = h[:longitude].to_f || h[:lng].to_f ||
|
120
|
+
@longitude = h[:longitude].to_f || h[:lng].to_f || @longitude
|
122
121
|
elsif h.is_a?(Array) && h.count == 2
|
123
122
|
@latitude = h.first.to_f
|
124
123
|
@longitude = h.last.to_f
|
@@ -142,7 +141,7 @@ module Parse
|
|
142
141
|
# Returns a tuple containing latitude and longitude
|
143
142
|
# @return [Array]
|
144
143
|
def to_a
|
145
|
-
[@latitude
|
144
|
+
[@latitude, @longitude]
|
146
145
|
end
|
147
146
|
|
148
147
|
# @!visibility private
|
@@ -161,7 +160,7 @@ module Parse
|
|
161
160
|
# is longitude instead of a GeoPoint.
|
162
161
|
# @return [Float] number of miles between geopoints.
|
163
162
|
# @see #distance_in_km
|
164
|
-
def distance_in_miles(geopoint,lng = nil)
|
163
|
+
def distance_in_miles(geopoint, lng = nil)
|
165
164
|
distance_in_km(geopoint, lng) * 0.621371
|
166
165
|
end
|
167
166
|
|
@@ -175,12 +174,12 @@ module Parse
|
|
175
174
|
# @param lng [Float] Longitude assuming that the first parameter is a latitude instead of a GeoPoint.
|
176
175
|
# @return [Float] number of miles between geopoints.
|
177
176
|
# @see #distance_in_miles
|
178
|
-
def distance_in_km(geopoint,lng = nil)
|
177
|
+
def distance_in_km(geopoint, lng = nil)
|
179
178
|
unless geopoint.is_a?(Parse::GeoPoint)
|
180
179
|
geopoint = Parse::GeoPoint.new(geopoint, lng)
|
181
180
|
end
|
182
181
|
|
183
|
-
dtor = Math::PI/180
|
182
|
+
dtor = Math::PI / 180
|
184
183
|
r = 6378.14
|
185
184
|
r_lat1 = self.latitude * dtor
|
186
185
|
r_lng1 = self.longitude * dtor
|
@@ -190,13 +189,10 @@ module Parse
|
|
190
189
|
delta_lat = r_lat1 - r_lat2
|
191
190
|
delta_lng = r_lng1 - r_lng2
|
192
191
|
|
193
|
-
a = (Math::sin(delta_lat/2.0) ** 2).to_f + (Math::cos(r_lat1) * Math::cos(r_lat2) * (
|
194
|
-
c = 2.0 * Math::atan2(Math::sqrt(a), Math::sqrt(1.0-a))
|
192
|
+
a = (Math::sin(delta_lat / 2.0) ** 2).to_f + (Math::cos(r_lat1) * Math::cos(r_lat2) * (Math::sin(delta_lng / 2.0) ** 2))
|
193
|
+
c = 2.0 * Math::atan2(Math::sqrt(a), Math::sqrt(1.0 - a))
|
195
194
|
d = r * c
|
196
195
|
d
|
197
196
|
end
|
198
|
-
|
199
|
-
|
200
197
|
end
|
201
|
-
|
202
198
|
end
|
data/lib/parse/model/model.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require_relative
|
4
|
+
require "active_model"
|
5
|
+
require "active_support"
|
6
|
+
require "active_support/inflector"
|
7
|
+
require "active_support/core_ext/object"
|
8
|
+
require "active_model_serializers"
|
9
|
+
require_relative "../client"
|
10
10
|
|
11
11
|
module Parse
|
12
12
|
# Find a corresponding Parse::Object subclass for this string or symbol
|
@@ -21,61 +21,59 @@ module Parse
|
|
21
21
|
# serialization, dirty tracking, callbacks, etc.
|
22
22
|
# @see ActiveModel
|
23
23
|
class Model
|
24
|
-
|
25
24
|
include Client::Connectable # allows easy default Parse::Client access
|
26
25
|
include ::ActiveModel::Model
|
27
26
|
include ::ActiveModel::Serializers::JSON # support for JSON Serializers
|
28
27
|
include ::ActiveModel::Dirty # adds dirty tracking support
|
29
28
|
include ::ActiveModel::Conversion
|
30
|
-
extend
|
31
|
-
extend
|
29
|
+
extend ::ActiveModel::Callbacks # callback support on save, update, delete, etc.
|
30
|
+
extend ::ActiveModel::Naming # provides the methods for getting class names from Model classes
|
32
31
|
|
33
32
|
# The name of the field in a hash that contains information about the type
|
34
33
|
# of data the hash represents.
|
35
|
-
TYPE_FIELD =
|
34
|
+
TYPE_FIELD = "__type".freeze
|
36
35
|
|
37
36
|
# The objectId field in Parse Objects.
|
38
|
-
OBJECT_ID
|
37
|
+
OBJECT_ID = "objectId".freeze
|
39
38
|
# @see OBJECT_ID
|
40
39
|
ID = "id".freeze
|
41
40
|
|
42
41
|
# The key field for getting class information.
|
43
|
-
KEY_CLASS_NAME
|
42
|
+
KEY_CLASS_NAME = "className".freeze
|
44
43
|
# @deprecated Use OBJECT_ID instead.
|
45
|
-
KEY_OBJECT_ID
|
44
|
+
KEY_OBJECT_ID = "objectId".freeze
|
46
45
|
# The key field for getting the created at date of an object hash.
|
47
|
-
KEY_CREATED_AT
|
46
|
+
KEY_CREATED_AT = "createdAt"
|
48
47
|
# The key field for getting the updated at date of an object hash.
|
49
|
-
KEY_UPDATED_AT
|
48
|
+
KEY_UPDATED_AT = "updatedAt"
|
50
49
|
# The collection for Users in Parse. Used by Parse::User.
|
51
|
-
CLASS_USER
|
50
|
+
CLASS_USER = "_User"
|
52
51
|
# The collection for Installations in Parse. Used by Parse::Installation.
|
53
|
-
CLASS_INSTALLATION =
|
52
|
+
CLASS_INSTALLATION = "_Installation"
|
54
53
|
# The collection for revocable Sessions in Parse. Used by Parse::Session.
|
55
|
-
CLASS_SESSION =
|
54
|
+
CLASS_SESSION = "_Session"
|
56
55
|
# The collection for Roles in Parse. Used by Parse::Role.
|
57
|
-
CLASS_ROLE =
|
56
|
+
CLASS_ROLE = "_Role"
|
58
57
|
# The collection for to store Products (in-App purchases) in Parse. Used by Parse::Product.
|
59
|
-
CLASS_PRODUCT =
|
58
|
+
CLASS_PRODUCT = "_Product"
|
60
59
|
# The type label for hashes containing file data. Used by Parse::File.
|
61
|
-
TYPE_FILE =
|
60
|
+
TYPE_FILE = "File"
|
62
61
|
# The type label for hashes containing geopoints. Used by Parse::GeoPoint.
|
63
|
-
TYPE_GEOPOINT =
|
62
|
+
TYPE_GEOPOINT = "GeoPoint"
|
64
63
|
# The type label for hashes containing a Parse object. Used by Parse::Object and subclasses.
|
65
|
-
TYPE_OBJECT =
|
64
|
+
TYPE_OBJECT = "Object"
|
66
65
|
# The type label for hashes containing a Parse date object. Used by Parse::Date.
|
67
|
-
TYPE_DATE =
|
66
|
+
TYPE_DATE = "Date"
|
68
67
|
# The type label for hashes containing 'byte' data. Used by Parse::Bytes.
|
69
|
-
TYPE_BYTES =
|
68
|
+
TYPE_BYTES = "Bytes"
|
70
69
|
# The type label for hashes containing ACL data. Used by Parse::ACL
|
71
|
-
TYPE_ACL =
|
70
|
+
TYPE_ACL = "ACL"
|
72
71
|
# The type label for hashes storing numeric data.
|
73
|
-
TYPE_NUMBER =
|
72
|
+
TYPE_NUMBER = "Number"
|
74
73
|
# The type label for hashes containing a Parse pointer.
|
75
|
-
TYPE_POINTER =
|
74
|
+
TYPE_POINTER = "Pointer"
|
76
75
|
# The type label for hashes representing relational data.
|
77
|
-
TYPE_RELATION =
|
78
|
-
|
76
|
+
TYPE_RELATION = "Relation"
|
79
77
|
|
80
78
|
# To support being able to have different ruby class names from the 'table'
|
81
79
|
# names used in Parse, we will need to have a dynamic lookup system where
|
@@ -115,7 +113,6 @@ module Parse
|
|
115
113
|
def raise_on_save_failure=(bool)
|
116
114
|
@global_raise_on_save_failure = bool
|
117
115
|
end
|
118
|
-
|
119
116
|
end
|
120
117
|
|
121
118
|
# Find a Parse::Model subclass matching this type or Pares collection name.
|
@@ -149,11 +146,8 @@ module Parse
|
|
149
146
|
@@model_cache[str] ||= Parse::Object.descendants.find do |f|
|
150
147
|
f.parse_class == str || f.parse_class == "_#{str}"
|
151
148
|
end
|
152
|
-
|
153
149
|
end
|
154
|
-
|
155
150
|
end
|
156
|
-
|
157
151
|
end
|
158
152
|
|
159
153
|
# Add extensions to the String class.
|
@@ -172,9 +166,9 @@ class String
|
|
172
166
|
# @return [String]
|
173
167
|
# @see Parse::Query.field_formatter
|
174
168
|
def columnize
|
175
|
-
|
176
|
-
|
177
|
-
|
169
|
+
return Parse::Model::OBJECT_ID if self == Parse::Model::ID
|
170
|
+
u = "_".freeze
|
171
|
+
(first == u ? sub(u, "") : self).camelize(:lower)
|
178
172
|
end
|
179
173
|
|
180
174
|
# Convert a string to a Parse class name. This method tries to find a
|
data/lib/parse/model/object.rb
CHANGED
@@ -1,42 +1,41 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
|
14
|
-
require_relative
|
15
|
-
require_relative
|
16
|
-
require_relative
|
17
|
-
require_relative
|
18
|
-
require_relative
|
19
|
-
require_relative
|
20
|
-
require_relative
|
21
|
-
require_relative
|
22
|
-
require_relative
|
23
|
-
require_relative
|
24
|
-
require_relative
|
25
|
-
require_relative
|
26
|
-
require_relative
|
27
|
-
require_relative
|
28
|
-
require_relative
|
29
|
-
require_relative
|
30
|
-
require_relative
|
31
|
-
require_relative
|
32
|
-
require_relative
|
33
|
-
require_relative
|
34
|
-
|
4
|
+
require "active_model"
|
5
|
+
require "active_support"
|
6
|
+
require "active_support/inflector"
|
7
|
+
require "active_support/core_ext"
|
8
|
+
require "active_support/core_ext/object"
|
9
|
+
require "active_support/core_ext/string"
|
10
|
+
require "active_model_serializers"
|
11
|
+
require "time"
|
12
|
+
require "open-uri"
|
13
|
+
|
14
|
+
require_relative "../client"
|
15
|
+
require_relative "model"
|
16
|
+
require_relative "pointer"
|
17
|
+
require_relative "geopoint"
|
18
|
+
require_relative "file"
|
19
|
+
require_relative "bytes"
|
20
|
+
require_relative "date"
|
21
|
+
require_relative "time_zone"
|
22
|
+
require_relative "acl"
|
23
|
+
require_relative "push"
|
24
|
+
require_relative "core/actions"
|
25
|
+
require_relative "core/fetching"
|
26
|
+
require_relative "core/querying"
|
27
|
+
require_relative "core/schema"
|
28
|
+
require_relative "core/properties"
|
29
|
+
require_relative "core/errors"
|
30
|
+
require_relative "core/builder"
|
31
|
+
require_relative "associations/has_one"
|
32
|
+
require_relative "associations/belongs_to"
|
33
|
+
require_relative "associations/has_many"
|
35
34
|
|
36
35
|
module Parse
|
37
36
|
# @return [Array] an array of registered Parse::Object subclasses.
|
38
37
|
def self.registered_classes
|
39
|
-
|
38
|
+
Parse::Object.descendants.map(&:parse_class).uniq
|
40
39
|
end
|
41
40
|
|
42
41
|
# @return [Array<Hash>] the list of all schemas for this application.
|
@@ -65,7 +64,7 @@ module Parse
|
|
65
64
|
# Alias shorter names of core Parse class names.
|
66
65
|
# Ex, alias Parse::User to User, Parse::Installation to Installation, etc.
|
67
66
|
def self.use_shortnames!
|
68
|
-
require_relative
|
67
|
+
require_relative "shortnames"
|
69
68
|
end
|
70
69
|
|
71
70
|
# This is the core class for all app specific Parse table subclasses. This class
|
@@ -139,7 +138,7 @@ module Parse
|
|
139
138
|
BASE_OBJECT_CLASS = "Parse::Object".freeze
|
140
139
|
|
141
140
|
# @return [Model::TYPE_OBJECT]
|
142
|
-
def __type; Parse::Model::TYPE_OBJECT; end
|
141
|
+
def __type; Parse::Model::TYPE_OBJECT; end
|
143
142
|
|
144
143
|
# Default ActiveModel::Callbacks
|
145
144
|
# @!group Callbacks
|
@@ -183,7 +182,6 @@ module Parse
|
|
183
182
|
# the remote Parse table is named 'Artist'. You may override this behavior by utilizing the `parse_class(<className>)` method
|
184
183
|
# to set it to something different.
|
185
184
|
class << self
|
186
|
-
|
187
185
|
attr_accessor :parse_class
|
188
186
|
attr_reader :default_acls
|
189
187
|
|
@@ -253,7 +251,6 @@ module Parse
|
|
253
251
|
def acl(acls, owner: nil)
|
254
252
|
raise "[#{self}.acl DEPRECATED] - Use `#{self}.default_acl` instead."
|
255
253
|
end
|
256
|
-
|
257
254
|
end # << self
|
258
255
|
|
259
256
|
# @return [String] the Parse class for this object.
|
@@ -261,6 +258,7 @@ module Parse
|
|
261
258
|
def parse_class
|
262
259
|
self.class.parse_class
|
263
260
|
end
|
261
|
+
|
264
262
|
alias_method :className, :parse_class
|
265
263
|
|
266
264
|
# @return [Hash] the schema structure for this Parse collection from the server.
|
@@ -347,7 +345,7 @@ module Parse
|
|
347
345
|
# @param opts [Hash] a set of options to send to fetch!
|
348
346
|
# @see Fetching#fetch!
|
349
347
|
def reload!(opts = {})
|
350
|
-
|
348
|
+
# get the values from the persistence layer
|
351
349
|
fetch!(opts)
|
352
350
|
clear_changes!
|
353
351
|
end
|
@@ -436,7 +434,7 @@ module Parse
|
|
436
434
|
# @return [String] a pretty-formatted JSON string
|
437
435
|
# @see JSON.pretty_generate
|
438
436
|
def pretty
|
439
|
-
JSON.pretty_generate(
|
437
|
+
JSON.pretty_generate(as_json)
|
440
438
|
end
|
441
439
|
|
442
440
|
# clear all change and dirty tracking information.
|
@@ -483,10 +481,10 @@ module Parse
|
|
483
481
|
o = Parse::Pointer.new className, (json[Parse::Model::OBJECT_ID] || json[:objectId])
|
484
482
|
end
|
485
483
|
return o
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
484
|
+
# rescue NameError => e
|
485
|
+
# puts "Parse::Object.build constant class error: #{e}"
|
486
|
+
# rescue Exception => e
|
487
|
+
# puts "Parse::Object.build error: #{e}"
|
490
488
|
end
|
491
489
|
|
492
490
|
# @!attribute id
|
@@ -521,13 +519,11 @@ module Parse
|
|
521
519
|
# @param key (see Parse::Object#[])
|
522
520
|
# @param value [Object] the value to set this property.
|
523
521
|
# @return [Object] the value passed in.
|
524
|
-
def []=(key,value)
|
522
|
+
def []=(key, value)
|
525
523
|
return unless self.class.fields[key.to_sym].present?
|
526
|
-
send("#{key}=",value)
|
524
|
+
send("#{key}=", value)
|
527
525
|
end
|
528
|
-
|
529
526
|
end
|
530
|
-
|
531
527
|
end
|
532
528
|
|
533
529
|
class Hash
|
@@ -540,7 +536,6 @@ class Hash
|
|
540
536
|
def parse_object
|
541
537
|
Parse::Object.build(self)
|
542
538
|
end
|
543
|
-
|
544
539
|
end
|
545
540
|
|
546
541
|
class Array
|
@@ -565,12 +560,11 @@ class Array
|
|
565
560
|
def parse_ids
|
566
561
|
parse_objects.map(&:id)
|
567
562
|
end
|
568
|
-
|
569
563
|
end
|
570
564
|
|
571
565
|
# Load all the core classes.
|
572
|
-
require_relative
|
573
|
-
require_relative
|
574
|
-
require_relative
|
575
|
-
require_relative
|
576
|
-
require_relative
|
566
|
+
require_relative "classes/installation"
|
567
|
+
require_relative "classes/product"
|
568
|
+
require_relative "classes/role"
|
569
|
+
require_relative "classes/session"
|
570
|
+
require_relative "classes/user"
|
data/lib/parse/model/pointer.rb
CHANGED
@@ -1,199 +1,200 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require_relative
|
4
|
+
require "active_model"
|
5
|
+
require "active_support"
|
6
|
+
require "active_support/inflector"
|
7
|
+
require "active_support/core_ext"
|
8
|
+
require "active_model_serializers"
|
9
|
+
require_relative "model"
|
10
|
+
|
10
11
|
module Parse
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
13
|
+
# The Pointer class represents the pointer type in Parse and is the superclass
|
14
|
+
# of Parse::Object types. A pointer can be considered a type of Parse::Object
|
15
|
+
# in which only the class name and id is known. In most cases, you may not
|
16
|
+
# deal with Parse::Pointer objects directly if you have defined all your
|
17
|
+
# Parse::Object subclasses.
|
18
|
+
#
|
19
|
+
# A `Parse::Pointer` only contains data about the specific Parse class and
|
20
|
+
# the `id` for the object. Therefore, creating an instance of any
|
21
|
+
# Parse::Object subclass with only the `:id` field set will be
|
22
|
+
# considered in "pointer" state even though its specific class is not
|
23
|
+
# `Parse::Pointer` type. The only case that you may have a Parse::Pointer
|
24
|
+
# is in the case where an object was received for one of your classes and
|
25
|
+
# the framework has no registered class handler for it.
|
26
|
+
# Assume you have the tables `Post`, `Comment` and `Author` defined in your
|
27
|
+
# remote Parse database, but have only defined `Post` and `Commentary`
|
28
|
+
# locally.
|
29
|
+
# @example
|
30
|
+
# class Post < Parse::Object
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# class Commentary < Parse::Object
|
34
|
+
# belongs_to :post
|
35
|
+
# belongs_to :author
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# comment = Commentary.first
|
39
|
+
# comment.post? # true because it is non-nil
|
40
|
+
# comment.artist? # true because it is non-nil
|
41
|
+
#
|
42
|
+
# # both are true because they are in a Pointer state
|
43
|
+
# comment.post.pointer? # true
|
44
|
+
# comment.author.pointer? # true
|
45
|
+
#
|
46
|
+
# # we have defined a Post class handler
|
47
|
+
# comment.post # <Post @parse_class="Post", @id="xdqcCqfngz">
|
48
|
+
#
|
49
|
+
# # we have not defined an Author class handler
|
50
|
+
# comment.author # <Parse::Pointer @parse_class="Author", @id="hZLbW6ofKC">
|
51
|
+
#
|
52
|
+
#
|
53
|
+
# comment.post.fetch # fetch the relation
|
54
|
+
# comment.post.pointer? # false, it is now a full object.
|
55
|
+
#
|
56
|
+
# The effect is that for any unknown classes that the framework encounters,
|
57
|
+
# it will generate Parse::Pointer instances until you define those classes
|
58
|
+
# with valid properties and associations. While this might be ok for some
|
59
|
+
# classes you do not use, we still recommend defining all your Parse classes
|
60
|
+
# locally in the framework.
|
61
|
+
#
|
62
|
+
# Once you have a subclass, you may also create a Parse::Pointer object using
|
63
|
+
# the _pointer_ method.
|
64
|
+
# @example
|
65
|
+
# Parse::User.pointer("123456") # => Parse::Pointer for "_User" class
|
66
|
+
#
|
67
|
+
# @see Parse::Object
|
68
|
+
class Pointer < Model
|
69
|
+
# The default attributes in a Parse Pointer hash.
|
70
|
+
ATTRIBUTES = { __type: :string, className: :string, objectId: :string }.freeze
|
71
|
+
# @return [String] the name of the Parse class for this pointer.
|
72
|
+
attr_accessor :parse_class
|
73
|
+
# @return [String] the objectId field
|
74
|
+
attr_accessor :id
|
75
|
+
|
76
|
+
# @return [Model::TYPE_POINTER]
|
77
|
+
def __type; Parse::Model::TYPE_POINTER; end
|
78
|
+
|
79
|
+
alias_method :className, :parse_class
|
80
|
+
# A Parse object as a className field and objectId. In ruby, we will use the
|
81
|
+
# id attribute method, but for usability, we will also alias it to objectId
|
82
|
+
alias_method :objectId, :id
|
83
|
+
|
84
|
+
# A Parse pointer only requires the name of the remote Parse collection name,
|
85
|
+
# and the `objectId` of the record.
|
86
|
+
# @param table [String] The Parse class name in the Parse database.
|
87
|
+
# @param oid [String] The objectId
|
88
|
+
def initialize(table, oid)
|
89
|
+
@parse_class = table.to_s
|
90
|
+
@id = oid.to_s
|
91
|
+
end
|
90
92
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
93
|
+
# @return [String] the name of the collection for this Pointer.
|
94
|
+
def parse_class
|
95
|
+
@parse_class
|
96
|
+
end
|
95
97
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
98
|
+
# @return [String] a string representing the class and id of this instance.
|
99
|
+
def sig
|
100
|
+
"#{@parse_class}##{id || "new"}"
|
101
|
+
end
|
100
102
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
103
|
+
# @return [Hash]
|
104
|
+
def attributes
|
105
|
+
ATTRIBUTES
|
106
|
+
end
|
105
107
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
108
|
+
# @return [Hash] serialized JSON structure
|
109
|
+
def json_hash
|
110
|
+
JSON.parse to_json
|
111
|
+
end
|
110
112
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
113
|
+
# Create a new pointer with the current class name and id. While this may not make sense
|
114
|
+
# for a pointer instance, Parse::Object subclasses use this inherited method to turn themselves into
|
115
|
+
# pointer objects.
|
116
|
+
# @example
|
117
|
+
# user = Parse::User.first
|
118
|
+
# user.pointer # => Parse::Pointer("_User", user.id)
|
119
|
+
#
|
120
|
+
# @return [Pointer] a new Pointer for this object.
|
121
|
+
# @see Parse::Object
|
122
|
+
def pointer
|
123
|
+
Pointer.new parse_class, @id
|
124
|
+
end
|
123
125
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
126
|
+
# Whether this instance is in pointer state. A pointer is determined
|
127
|
+
# if we have a parse class and an id, but no created_at or updated_at fields.
|
128
|
+
# @return [Boolean] true if instance is in pointer state.
|
129
|
+
def pointer?
|
130
|
+
present? && @created_at.blank? && @updated_at.blank?
|
131
|
+
end
|
130
132
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
133
|
+
# Returns true if the data for this instance has been fetched. Because of some autofetching
|
134
|
+
# mechanisms, this is useful to know whether the object already has data without actually causing
|
135
|
+
# a fetch of the data.
|
136
|
+
# @return [Boolean] true if not in pointer state.
|
137
|
+
def fetched?
|
138
|
+
present? && pointer? == false
|
139
|
+
end
|
138
140
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
141
|
+
# This method is a general implementation that gets overriden by Parse::Object subclass.
|
142
|
+
# Given the class name and the id, we will go to Parse and fetch the actual record, returning the
|
143
|
+
# JSON object.
|
144
|
+
# @return [Parse::Object] the fetched Parse::Object, nil otherwise.
|
145
|
+
def fetch
|
146
|
+
response = client.fetch_object(parse_class, id)
|
147
|
+
return nil if response.error?
|
148
|
+
response.result
|
149
|
+
end
|
148
150
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
alias_method :eql?, :==
|
158
|
-
|
159
|
-
# Compute a hash-code for this object. It is calculated
|
160
|
-
# by combining the Parse class name, the {Parse::Object#id} field and
|
161
|
-
# any pending changes.
|
162
|
-
#
|
163
|
-
# Two objects with the same content will have the same hash code
|
164
|
-
# (and will compare using eql?).
|
165
|
-
# @return [Fixnum]
|
166
|
-
def hash
|
167
|
-
"#{parse_class}#{id}#{changes.to_s}".hash
|
168
|
-
end
|
151
|
+
# Two Parse::Pointers (or Parse::Objects) are equal if both of them have
|
152
|
+
# the same Parse class and the same id.
|
153
|
+
# @return [Boolean]
|
154
|
+
def ==(o)
|
155
|
+
return false unless o.is_a?(Pointer)
|
156
|
+
#only equal if the Parse class and object ID are the same.
|
157
|
+
self.parse_class == o.parse_class && id == o.id
|
158
|
+
end
|
169
159
|
|
170
|
-
|
171
|
-
def present?
|
172
|
-
parse_class.present? && @id.present?
|
173
|
-
end
|
160
|
+
alias_method :eql?, :==
|
174
161
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
162
|
+
# Compute a hash-code for this object. It is calculated
|
163
|
+
# by combining the Parse class name, the {Parse::Object#id} field and
|
164
|
+
# any pending changes.
|
165
|
+
#
|
166
|
+
# Two objects with the same content will have the same hash code
|
167
|
+
# (and will compare using eql?).
|
168
|
+
# @return [Fixnum]
|
169
|
+
def hash
|
170
|
+
"#{parse_class}#{id}#{changes.to_s}".hash
|
171
|
+
end
|
184
172
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
# @return [Object]
|
190
|
-
def []=(key,value)
|
191
|
-
return unless [:id,:objectId,:className].include?(key.to_sym)
|
192
|
-
send("#{key}=",value)
|
193
|
-
end
|
173
|
+
# @return [Boolean] true if instance has a Parse class and an id.
|
174
|
+
def present?
|
175
|
+
parse_class.present? && @id.present?
|
176
|
+
end
|
194
177
|
|
178
|
+
# Access the pointer properties through hash accessor. This is done for
|
179
|
+
# compatibility with the hash access of a Parse::Object. This method
|
180
|
+
# returns nil if the key is not one of: :id, :objectId, or :className.
|
181
|
+
# @param key [String] the name of the property.
|
182
|
+
# @return [Object] the value for this key.
|
183
|
+
def [](key)
|
184
|
+
return nil unless [:id, :objectId, :className].include?(key.to_sym)
|
185
|
+
send(key)
|
195
186
|
end
|
196
187
|
|
188
|
+
# Set the pointer properties through hash accessor. This is done for
|
189
|
+
# compatibility with the hash access of a Parse::Object. This method
|
190
|
+
# does nothing if the key is not one of: :id, :objectId, or :className.
|
191
|
+
# @param key (see #[])
|
192
|
+
# @return [Object]
|
193
|
+
def []=(key, value)
|
194
|
+
return unless [:id, :objectId, :className].include?(key.to_sym)
|
195
|
+
send("#{key}=", value)
|
196
|
+
end
|
197
|
+
end
|
197
198
|
end
|
198
199
|
|
199
200
|
# extensions
|