parse-stack 1.8.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.solargraph.yml +23 -0
  3. data/.travis.yml +0 -1
  4. data/Gemfile +13 -12
  5. data/Gemfile.lock +88 -51
  6. data/README.md +2 -4
  7. data/Rakefile +14 -14
  8. data/lib/parse/api/aggregate.rb +4 -7
  9. data/lib/parse/api/all.rb +1 -1
  10. data/lib/parse/api/analytics.rb +0 -3
  11. data/lib/parse/api/batch.rb +3 -5
  12. data/lib/parse/api/cloud_functions.rb +0 -3
  13. data/lib/parse/api/config.rb +0 -4
  14. data/lib/parse/api/files.rb +3 -7
  15. data/lib/parse/api/hooks.rb +4 -8
  16. data/lib/parse/api/objects.rb +7 -12
  17. data/lib/parse/api/push.rb +0 -4
  18. data/lib/parse/api/schema.rb +2 -6
  19. data/lib/parse/api/server.rb +4 -7
  20. data/lib/parse/api/sessions.rb +2 -5
  21. data/lib/parse/api/users.rb +9 -14
  22. data/lib/parse/client.rb +54 -50
  23. data/lib/parse/client/authentication.rb +29 -33
  24. data/lib/parse/client/batch.rb +8 -11
  25. data/lib/parse/client/body_builder.rb +19 -20
  26. data/lib/parse/client/caching.rb +23 -28
  27. data/lib/parse/client/protocol.rb +11 -12
  28. data/lib/parse/client/request.rb +4 -6
  29. data/lib/parse/client/response.rb +5 -7
  30. data/lib/parse/model/acl.rb +14 -12
  31. data/lib/parse/model/associations/belongs_to.rb +14 -21
  32. data/lib/parse/model/associations/collection_proxy.rb +328 -329
  33. data/lib/parse/model/associations/has_many.rb +18 -25
  34. data/lib/parse/model/associations/has_one.rb +6 -11
  35. data/lib/parse/model/associations/pointer_collection_proxy.rb +5 -8
  36. data/lib/parse/model/associations/relation_collection_proxy.rb +5 -9
  37. data/lib/parse/model/bytes.rb +8 -10
  38. data/lib/parse/model/classes/installation.rb +2 -4
  39. data/lib/parse/model/classes/product.rb +2 -5
  40. data/lib/parse/model/classes/role.rb +3 -5
  41. data/lib/parse/model/classes/session.rb +2 -5
  42. data/lib/parse/model/classes/user.rb +20 -16
  43. data/lib/parse/model/core/actions.rb +31 -46
  44. data/lib/parse/model/core/builder.rb +6 -6
  45. data/lib/parse/model/core/errors.rb +0 -1
  46. data/lib/parse/model/core/fetching.rb +45 -50
  47. data/lib/parse/model/core/properties.rb +51 -66
  48. data/lib/parse/model/core/querying.rb +291 -294
  49. data/lib/parse/model/core/schema.rb +89 -92
  50. data/lib/parse/model/date.rb +16 -17
  51. data/lib/parse/model/file.rb +171 -174
  52. data/lib/parse/model/geopoint.rb +12 -16
  53. data/lib/parse/model/model.rb +31 -37
  54. data/lib/parse/model/object.rb +47 -53
  55. data/lib/parse/model/pointer.rb +177 -176
  56. data/lib/parse/model/push.rb +8 -10
  57. data/lib/parse/model/shortnames.rb +1 -2
  58. data/lib/parse/model/time_zone.rb +3 -5
  59. data/lib/parse/query.rb +34 -35
  60. data/lib/parse/query/constraint.rb +4 -6
  61. data/lib/parse/query/constraints.rb +21 -29
  62. data/lib/parse/query/operation.rb +8 -11
  63. data/lib/parse/query/ordering.rb +45 -49
  64. data/lib/parse/stack.rb +11 -12
  65. data/lib/parse/stack/generators/rails.rb +28 -30
  66. data/lib/parse/stack/generators/templates/model.erb +5 -6
  67. data/lib/parse/stack/generators/templates/model_installation.rb +0 -1
  68. data/lib/parse/stack/generators/templates/model_role.rb +0 -1
  69. data/lib/parse/stack/generators/templates/model_session.rb +0 -1
  70. data/lib/parse/stack/generators/templates/model_user.rb +0 -1
  71. data/lib/parse/stack/generators/templates/parse.rb +9 -9
  72. data/lib/parse/stack/generators/templates/webhooks.rb +1 -2
  73. data/lib/parse/stack/railtie.rb +2 -4
  74. data/lib/parse/stack/tasks.rb +70 -86
  75. data/lib/parse/stack/version.rb +1 -1
  76. data/lib/parse/webhooks.rb +19 -26
  77. data/lib/parse/webhooks/payload.rb +26 -28
  78. data/lib/parse/webhooks/registration.rb +23 -31
  79. data/parse-stack.gemspec +25 -25
  80. data/parse-stack.png +0 -0
  81. metadata +13 -7
  82. data/.github/parse-ruby-sdk.png +0 -0
@@ -1,24 +1,21 @@
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'
8
- require 'time'
9
- require 'parallel'
10
- require_relative '../../client/request'
11
- require_relative 'fetching'
12
-
4
+ require "active_model"
5
+ require "active_support"
6
+ require "active_support/inflector"
7
+ require "active_support/core_ext"
8
+ require "time"
9
+ require "parallel"
10
+ require_relative "../../client/request"
11
+ require_relative "fetching"
13
12
 
14
13
  module Parse
15
-
16
14
  class Query
17
15
 
18
-
19
16
  # Supporting the `all` class method to be used in scope chaining with queries.
20
17
  # @!visibility private
21
- def all(expressions = {limit: :max})
18
+ def all(expressions = { limit: :max })
22
19
  conditions(expressions)
23
20
  return results(&Proc.new) if block_given?
24
21
  results
@@ -49,7 +46,6 @@ module Parse
49
46
  klass.save_all(hash_constraints, &Proc.new) if block_given?
50
47
  klass.save_all(hash_constraints)
51
48
  end
52
-
53
49
  end
54
50
 
55
51
  # A Parse::RelationAction is special operation that adds one object to a relational
@@ -80,16 +76,12 @@ module Parse
80
76
 
81
77
  # @return [Hash] a hash representing a relation operation.
82
78
  def as_json(*args)
83
- { @key =>
84
- {
85
- "__op" => ( @polarity == true ? ADD : REMOVE ),
86
- "objects" => objects.parse_pointers
87
- }
88
- }.as_json
79
+ { @key => {
80
+ "__op" => (@polarity == true ? ADD : REMOVE),
81
+ "objects" => objects.parse_pointers,
82
+ } }.as_json
89
83
  end
90
-
91
84
  end
92
-
93
85
  end
94
86
 
95
87
  # This module is mainly all the basic orm operations. To support batching actions,
@@ -132,7 +124,7 @@ module Parse
132
124
  # @example
133
125
  # # globally across all models
134
126
  # Parse::Model.raise_on_save_failure = true
135
- # Song.raise_on_save_failure = true # per-model
127
+ # Song.raise_on_save_failure = true # per-model
136
128
  #
137
129
  # # or per-instance raise on failure
138
130
  # song.save!
@@ -156,7 +148,6 @@ module Parse
156
148
  # @param resource_attrs [Hash] a set of attribute values to be applied if an object was not found.
157
149
  # @return [Parse::Object] a Parse::Object, whether found by the query or newly created.
158
150
  def first_or_create(query_attrs = {}, resource_attrs = {})
159
-
160
151
  query_attrs = query_attrs.symbolize_keys
161
152
  resource_attrs = resource_attrs.symbolize_keys
162
153
  obj = query(query_attrs).first
@@ -205,7 +196,7 @@ module Parse
205
196
  def save_all(constraints = {})
206
197
  invalid_constraints = constraints.keys.any? do |k|
207
198
  (k == :updated_at || k == :updatedAt) ||
208
- ( k.is_a?(Parse::Operation) && (k.operand == :updated_at || k.operand == :updatedAt) )
199
+ (k.is_a?(Parse::Operation) && (k.operand == :updated_at || k.operand == :updatedAt))
209
200
  end
210
201
  if invalid_constraints
211
202
  raise ArgumentError,
@@ -267,14 +258,12 @@ module Parse
267
258
  warn "[#{self}.save_all] Reached anchor date #{anchor_date} < #{cursor.updated_at}"
268
259
  break cursor
269
260
  end
270
-
271
261
  end
272
262
 
273
263
  has_errors ||= batch.error?
274
264
  end
275
265
  not has_errors
276
266
  end
277
-
278
267
  end # ClassMethods
279
268
 
280
269
  # Perform an atomic operation on this field. This operation is done on the
@@ -295,7 +284,7 @@ module Parse
295
284
  op_hash = { field => op_hash }.as_json
296
285
  end
297
286
 
298
- response = client.update_object(parse_class, id, op_hash, session_token: _session_token )
287
+ response = client.update_object(parse_class, id, op_hash, session_token: _session_token)
299
288
  if response.error?
300
289
  puts "[#{parse_class}:#{field} Operation] #{response.error}"
301
290
  end
@@ -307,7 +296,7 @@ module Parse
307
296
  # @param objects [Array] the set of items to add to this field.
308
297
  # @return [Boolean] whether it was successful
309
298
  # @see #operate_field!
310
- def op_add!(field,objects)
299
+ def op_add!(field, objects)
311
300
  operate_field! field, { __op: :Add, objects: objects }
312
301
  end
313
302
 
@@ -317,7 +306,7 @@ module Parse
317
306
  # @param objects [Array] the set of items to add uniquely to this field.
318
307
  # @return [Boolean] whether it was successful
319
308
  # @see #operate_field!
320
- def op_add_unique!(field,objects)
309
+ def op_add_unique!(field, objects)
321
310
  operate_field! field, { __op: :AddUnique, objects: objects }
322
311
  end
323
312
 
@@ -377,7 +366,7 @@ module Parse
377
366
  def destroy_request
378
367
  return nil unless @id.present?
379
368
  uri = self.uri_path
380
- r = Request.new( :delete, uri )
369
+ r = Request.new(:delete, uri)
381
370
  r.tag = object_id
382
371
  r
383
372
  end
@@ -401,7 +390,7 @@ module Parse
401
390
  if attribute_changes? || force
402
391
  # if it's new, then we should call :post for creating the object.
403
392
  method = new? ? :post : :put
404
- r = Request.new( method, uri, body: attribute_updates)
393
+ r = Request.new(method, uri, body: attribute_updates)
405
394
  r.tag = object_id
406
395
  requests << r
407
396
  end
@@ -411,7 +400,7 @@ module Parse
411
400
  if @id.present? && relation_changes?
412
401
  relation_change_operations.each do |ops|
413
402
  next if ops.empty?
414
- r = Request.new( :put, uri, body: ops)
403
+ r = Request.new(:put, uri, body: ops)
415
404
  r.tag = object_id
416
405
  requests << r
417
406
  end
@@ -515,7 +504,7 @@ module Parse
515
504
  if relation_changes?
516
505
  # get the list of changed keys
517
506
  changed_attribute_keys = changed - relations.keys.map(&:to_s)
518
- clear_attribute_changes( changed_attribute_keys )
507
+ clear_attribute_changes(changed_attribute_keys)
519
508
  success = update_relations
520
509
  if success
521
510
  changes_applied!
@@ -528,7 +517,6 @@ module Parse
528
517
  elsif self.class.raise_on_save_failure || autoraise.present?
529
518
  raise Parse::RecordNotSaved.new(self), "Failed to create or save attributes. #{self.parse_class} was not saved."
530
519
  end
531
-
532
520
  end #callbacks
533
521
  @_session_token = nil
534
522
  success
@@ -543,7 +531,6 @@ module Parse
543
531
  save(autoraise: true, session: session)
544
532
  end
545
533
 
546
-
547
534
  # Delete this record from the Parse collection. Only valid if this object has an `id`.
548
535
  # This will run all the `destroy` callbacks.
549
536
  # @param session [String] a session token if you want to apply ACLs for a user in this operation.
@@ -577,12 +564,13 @@ module Parse
577
564
  def changes_payload
578
565
  h = attribute_updates
579
566
  if relation_changes?
580
- r = relation_change_operations.select { |s| s.present? }.first
567
+ r = relation_change_operations.select { |s| s.present? }.first
581
568
  h.merge!(r) if r.present?
582
569
  end
583
570
  #h.merge!(className: parse_class) unless h.empty?
584
571
  h.as_json
585
572
  end
573
+
586
574
  alias_method :update_payload, :changes_payload
587
575
 
588
576
  # Generates an array with two entries for addition and removal operations. The first entry
@@ -592,12 +580,12 @@ module Parse
592
580
  # @return [Array] an array with two hashes; the first is a hash of all the addition operations and
593
581
  # the second hash, all the remove operations.
594
582
  def relation_change_operations
595
- return [{},{}] unless relation_changes?
583
+ return [{}, {}] unless relation_changes?
596
584
 
597
585
  additions = []
598
586
  removals = []
599
587
  # go through all the additions of a collection and generate an action to add.
600
- relation_updates.each do |field,collection|
588
+ relation_updates.each do |field, collection|
601
589
  if collection.additions.count > 0
602
590
  additions.push Parse::RelationAction.new(field, objects: collection.additions, polarity: true)
603
591
  end
@@ -607,8 +595,8 @@ module Parse
607
595
  end
608
596
  end
609
597
  # merge all additions and removals into one large hash
610
- additions = additions.reduce({}) { |m,v| m.merge! v.as_json }
611
- removals = removals.reduce({}) { |m,v| m.merge! v.as_json }
598
+ additions = additions.reduce({}) { |m, v| m.merge! v.as_json }
599
+ removals = removals.reduce({}) { |m, v| m.merge! v.as_json }
612
600
  [additions, removals]
613
601
  end
614
602
 
@@ -656,7 +644,7 @@ module Parse
656
644
  # @return [Hash]
657
645
  def set_attributes!(hash, dirty_track = false)
658
646
  return unless hash.is_a?(Hash)
659
- hash.each do |k,v|
647
+ hash.each do |k, v|
660
648
  next if k == Parse::Model::OBJECT_ID || k == Parse::Model::ID
661
649
  method = "#{k}_set_attribute!"
662
650
  send(method, v, dirty_track) if respond_to?(method)
@@ -667,23 +655,20 @@ module Parse
667
655
  # local attributes.
668
656
  def changes_applied!
669
657
  # find all fields that are of type :array
670
- fields(:array) do |key,v|
658
+ fields(:array) do |key, v|
671
659
  proxy = send(key)
672
660
  # clear changes
673
661
  proxy.changes_applied! if proxy.respond_to?(:changes_applied!)
674
662
  end
675
663
 
676
664
  # for all relational fields,
677
- relations.each do |key,v|
665
+ relations.each do |key, v|
678
666
  proxy = send(key)
679
667
  # clear changes if they support the method.
680
668
  proxy.changes_applied! if proxy.respond_to?(:changes_applied!)
681
669
  end
682
670
  changes_applied
683
671
  end
684
-
685
-
686
672
  end
687
673
  end
688
-
689
674
  end
@@ -1,10 +1,10 @@
1
1
  # encoding: UTF-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'active_support'
5
- require 'active_support/inflector'
6
- require 'active_support/core_ext'
7
- require_relative '../object'
4
+ require "active_support"
5
+ require "active_support/inflector"
6
+ require "active_support/core_ext"
7
+ require_relative "../object"
8
8
 
9
9
  module Parse
10
10
  # Create all Parse::Object subclasses, including their properties and inferred
@@ -60,9 +60,9 @@ module Parse
60
60
 
61
61
  data_type = type[:type].downcase.to_sym
62
62
  if data_type == :pointer
63
- klass.belongs_to key, as: type[:targetClass], field: field
63
+ klass.belongs_to key, as: type[:targetClass], field: field
64
64
  elsif data_type == :relation
65
- klass.has_many key, through: :relation, as: type[:targetClass], field: field
65
+ klass.has_many key, through: :relation, as: type[:targetClass], field: field
66
66
  else
67
67
  klass.property key, data_type, field: field
68
68
  end
@@ -5,5 +5,4 @@
5
5
  module Parse
6
6
  # An abstract parent class for all Parse::Error types.
7
7
  class Error < StandardError; end
8
-
9
8
  end
@@ -1,8 +1,8 @@
1
1
  # encoding: UTF-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'time'
5
- require 'parallel'
4
+ require "time"
5
+ require "parallel"
6
6
 
7
7
  module Parse
8
8
  # Combines a set of core functionality for {Parse::Object} and its subclasses.
@@ -48,62 +48,57 @@ module Parse
48
48
  send :fetch
49
49
  @fetch_lock = false
50
50
  end
51
-
52
51
  end
53
-
54
52
  end
55
53
  end
56
54
  end
57
55
 
58
-
59
-
60
56
  class Array
61
57
 
62
- # Perform a threaded each iteration on a set of array items.
63
- # @param threads [Integer] the maximum number of threads to spawn/
64
- # @yield the block for the each iteration.
65
- # @return [self]
66
- # @see Array#each
67
- # @see https://github.com/grosser/parallel Parallel
68
- def threaded_each(threads = 2, &block)
69
- Parallel.each(self, {in_threads: threads}, &block)
70
- end
71
-
72
- # Perform a threaded map operation on a set of array items.
73
- # @param threads [Integer] the maximum number of threads to spawn
74
- # @yield the block for the map iteration.
75
- # @return [Array] the resultant array from the map.
76
- # @see Array#map
77
- # @see https://github.com/grosser/parallel Parallel
78
- def threaded_map(threads = 2, &block)
79
- Parallel.map(self, {in_threads: threads}, &block)
80
- end
58
+ # Perform a threaded each iteration on a set of array items.
59
+ # @param threads [Integer] the maximum number of threads to spawn/
60
+ # @yield the block for the each iteration.
61
+ # @return [self]
62
+ # @see Array#each
63
+ # @see https://github.com/grosser/parallel Parallel
64
+ def threaded_each(threads = 2, &block)
65
+ Parallel.each(self, { in_threads: threads }, &block)
66
+ end
81
67
 
82
- # Fetches all the objects in the array even if they are not in a Pointer state.
83
- # @param lookup [Symbol] The methodology to use for HTTP requests. Use :parallel
84
- # to fetch all objects in parallel HTTP requests. Set to anything else to
85
- # perform requests serially.
86
- # @return [Array<Parse::Object>] an array of fetched Parse::Objects.
87
- # @see Array#fetch_objects
88
- def fetch_objects!(lookup = :parallel)
89
- # this gets all valid parse objects from the array
90
- items = valid_parse_objects
91
- lookup == :parallel ? items.threaded_each(2,&:fetch!) : items.each(&:fetch!)
92
- #self.replace items
93
- self #return for chaining.
94
- end
68
+ # Perform a threaded map operation on a set of array items.
69
+ # @param threads [Integer] the maximum number of threads to spawn
70
+ # @yield the block for the map iteration.
71
+ # @return [Array] the resultant array from the map.
72
+ # @see Array#map
73
+ # @see https://github.com/grosser/parallel Parallel
74
+ def threaded_map(threads = 2, &block)
75
+ Parallel.map(self, { in_threads: threads }, &block)
76
+ end
95
77
 
96
- # Fetches all the objects in the array that are in Pointer state.
97
- # @param lookup [Symbol] The methodology to use for HTTP requests. Use :parallel
98
- # to fetch all objects in parallel HTTP requests. Set to anything else to
99
- # perform requests serially.
100
- # @return [Array<Parse::Object>] an array of fetched Parse::Objects.
101
- # @see Array#fetch_objects!
102
- def fetch_objects(lookup = :parallel)
103
- items = valid_parse_objects
104
- lookup == :parallel ? items.threaded_each(2,&:fetch) : items.each(&:fetch)
105
- #self.replace items
106
- self
107
- end
78
+ # Fetches all the objects in the array even if they are not in a Pointer state.
79
+ # @param lookup [Symbol] The methodology to use for HTTP requests. Use :parallel
80
+ # to fetch all objects in parallel HTTP requests. Set to anything else to
81
+ # perform requests serially.
82
+ # @return [Array<Parse::Object>] an array of fetched Parse::Objects.
83
+ # @see Array#fetch_objects
84
+ def fetch_objects!(lookup = :parallel)
85
+ # this gets all valid parse objects from the array
86
+ items = valid_parse_objects
87
+ lookup == :parallel ? items.threaded_each(2, &:fetch!) : items.each(&:fetch!)
88
+ #self.replace items
89
+ self #return for chaining.
90
+ end
108
91
 
92
+ # Fetches all the objects in the array that are in Pointer state.
93
+ # @param lookup [Symbol] The methodology to use for HTTP requests. Use :parallel
94
+ # to fetch all objects in parallel HTTP requests. Set to anything else to
95
+ # perform requests serially.
96
+ # @return [Array<Parse::Object>] an array of fetched Parse::Objects.
97
+ # @see Array#fetch_objects!
98
+ def fetch_objects(lookup = :parallel)
99
+ items = valid_parse_objects
100
+ lookup == :parallel ? items.threaded_each(2, &:fetch) : items.each(&:fetch)
101
+ #self.replace items
102
+ self
103
+ end
109
104
  end
@@ -1,18 +1,17 @@
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'
8
- require 'active_support/core_ext/object'
9
- require 'active_support/inflector'
10
- require 'active_model_serializers'
11
- require 'active_support/inflector'
12
- require 'active_model_serializers'
13
- require 'active_support/hash_with_indifferent_access'
14
- require 'time'
15
-
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/inflector"
10
+ require "active_model_serializers"
11
+ require "active_support/inflector"
12
+ require "active_model_serializers"
13
+ require "active_support/hash_with_indifferent_access"
14
+ require "time"
16
15
 
17
16
  module Parse
18
17
 
@@ -22,15 +21,15 @@ module Parse
22
21
  # These are the base types supported by Parse.
23
22
  TYPES = [:string, :relation, :integer, :float, :boolean, :date, :array, :file, :geopoint, :bytes, :object, :acl, :timezone].freeze
24
23
  # These are the base mappings of the remote field name types.
25
- BASE = {objectId: :string, createdAt: :date, updatedAt: :date, ACL: :acl}.freeze
24
+ BASE = { objectId: :string, createdAt: :date, updatedAt: :date, ACL: :acl }.freeze
26
25
  # The list of properties that are part of all objects
27
26
  BASE_KEYS = [:id, :created_at, :updated_at].freeze
28
27
  # Default hash map of local attribute name to remote column name
29
- BASE_FIELD_MAP = {id: :objectId, created_at: :createdAt, updated_at: :updatedAt, acl: :ACL}.freeze
28
+ BASE_FIELD_MAP = { id: :objectId, created_at: :createdAt, updated_at: :updatedAt, acl: :ACL }.freeze
30
29
  # The delete operation hash.
31
- CORE_FIELDS = {id: :string, created_at: :date, updated_at: :date, acl: :acl}.freeze
30
+ CORE_FIELDS = { id: :string, created_at: :date, updated_at: :date, acl: :acl }.freeze
32
31
  # The delete operation hash.
33
- DELETE_OP = {"__op"=>"Delete"}.freeze
32
+ DELETE_OP = { "__op" => "Delete" }.freeze
34
33
  # @!visibility private
35
34
  def self.included(base)
36
35
  base.extend(ClassMethods)
@@ -49,7 +48,7 @@ module Parse
49
48
  @fields ||= (self == Parse::Object ? CORE_FIELDS : Parse::Object.fields).dup
50
49
  if type.present?
51
50
  type = type.to_sym
52
- return @fields.select { |k,v| v == type }
51
+ return @fields.select { |k, v| v == type }
53
52
  end
54
53
  @fields
55
54
  end
@@ -101,7 +100,6 @@ module Parse
101
100
  # "myDate" (lower-first-camelcase) with a Parse data type of Date.
102
101
  # You can override the implicit naming behavior by passing the option :field to override.
103
102
  def property(key, data_type = :string, **opts)
104
-
105
103
  key = key.to_sym
106
104
  ivar = :"@#{key}"
107
105
  will_change_method = :"#{key}_will_change!"
@@ -125,25 +123,24 @@ module Parse
125
123
 
126
124
  # set defaults
127
125
  opts = { required: false,
128
- alias: true,
129
- symbolize: false,
130
- enum: nil,
131
- scopes: true,
132
- _prefix: nil,
133
- _suffix: false,
134
- field: key.to_s.camelize(:lower)
135
- }.merge( opts )
126
+ alias: true,
127
+ symbolize: false,
128
+ enum: nil,
129
+ scopes: true,
130
+ _prefix: nil,
131
+ _suffix: false,
132
+ field: key.to_s.camelize(:lower) }.merge(opts)
136
133
  #By default, the remote field name is a lower-first-camelcase version of the key
137
134
  # it can be overriden by the :field parameter
138
135
  parse_field = opts[:field].to_sym
139
136
  # if this is a custom property that is already defined, OR it is a subclass trying to define a core property
140
137
  # then warn and exit.
141
- if (self.fields[key].present? && BASE_FIELD_MAP[key].nil?) || ( self < Parse::Object && BASE_FIELD_MAP.has_key?(key) )
138
+ if (self.fields[key].present? && BASE_FIELD_MAP[key].nil?) || (self < Parse::Object && BASE_FIELD_MAP.has_key?(key))
142
139
  warn "Property #{self}##{key} already defined with data type :#{data_type}. Will be ignored."
143
140
  return false
144
141
  end
145
142
  # We keep the list of fields that are on the remote Parse store
146
- if self.fields[parse_field].present? || ( self < Parse::Object && BASE.has_key?(parse_field) )
143
+ if self.fields[parse_field].present? || (self < Parse::Object && BASE.has_key?(parse_field))
147
144
  warn "Alias property #{self}##{parse_field} conflicts with previously defined property. Will be ignored."
148
145
  return false
149
146
  # raise ArgumentError
@@ -152,13 +149,13 @@ module Parse
152
149
  define_attribute_methods key
153
150
 
154
151
  # this hash keeps list of attributes (based on remote fields) and their data types
155
- self.attributes.merge!( parse_field => data_type )
152
+ self.attributes.merge!(parse_field => data_type)
156
153
  # this maps all the possible attribute fields and their data types. We use both local
157
154
  # keys and remote keys because when we receive a remote object that has the remote field name
158
155
  # we need to know what the data type conversion should be.
159
- self.fields.merge!( key => data_type, parse_field => data_type )
156
+ self.fields.merge!(key => data_type, parse_field => data_type)
160
157
  # This creates a mapping between the local field and the remote field name.
161
- self.field_map.merge!( key => parse_field )
158
+ self.field_map.merge!(key => parse_field)
162
159
 
163
160
  # if the field is marked as required, then add validations
164
161
  if opts[:required]
@@ -183,7 +180,6 @@ module Parse
183
180
  is_enum_type = opts[:enum].nil? == false
184
181
 
185
182
  if is_enum_type
186
-
187
183
  unless data_type == :string
188
184
  raise ArgumentError, "Property #{self}##{parse_field} :enum option is only supported on :string data types."
189
185
  end
@@ -196,7 +192,7 @@ module Parse
196
192
 
197
193
  enum_values = enum_values.dup.map(&:to_sym).freeze
198
194
 
199
- self.enums.merge!( key => enum_values )
195
+ self.enums.merge!(key => enum_values)
200
196
  allow_nil = opts[:required] == false
201
197
  validates key, inclusion: { in: enum_values }, allow_nil: allow_nil
202
198
 
@@ -217,9 +213,7 @@ module Parse
217
213
 
218
214
  class_method_name = prefix_or_key.to_s.pluralize.to_sym
219
215
  if singleton_class.method_defined?(class_method_name)
220
- raise ArgumentError, "You tried to define an enum named `#{key}` for #{self} " + \
221
- "but this will generate a method `#{self}.#{class_method_name}` " + \
222
- " which is already defined. Try using :_suffix or :_prefix options."
216
+ raise ArgumentError, "You tried to define an enum named `#{key}` for #{self} " + "but this will generate a method `#{self}.#{class_method_name}` " + " which is already defined. Try using :_suffix or :_prefix options."
223
217
  end
224
218
 
225
219
  define_singleton_method(class_method_name) { enum_values }
@@ -239,18 +233,14 @@ module Parse
239
233
  elsif prefix.present?
240
234
  method_name = :"#{prefix}_#{enum}"
241
235
  end
242
- self.scope method_name, ->(ex = {}){ ex.merge!(key => enum); query( ex ) }
243
-
236
+ self.scope method_name, ->(ex = {}) { ex.merge!(key => enum); query(ex) }
244
237
 
245
238
  define_method("#{method_name}!") { send set_attribute_method, enum, true }
246
239
  define_method("#{method_name}?") { enum == send(key).to_s.to_sym }
247
240
  end
248
241
  end # unless scopes
249
-
250
242
  end # if is enum
251
243
 
252
-
253
-
254
244
  symbolize_value = opts[:symbolize]
255
245
 
256
246
  #only support symbolization of string data types
@@ -271,7 +261,6 @@ module Parse
271
261
  # we'll assume it's just a plain literal value
272
262
  default_value.is_a?(Proc) ? default_value.call(self) : default_value
273
263
  end
274
-
275
264
  end
276
265
 
277
266
  # We define a getter with the key
@@ -295,12 +284,11 @@ module Parse
295
284
  # if value is nil (even after fetching), then lets see if the developer
296
285
  # set a default value for this attribute.
297
286
  if value.nil? && respond_to?("#{key}_default")
298
-
299
- value = send("#{key}_default")
300
- value = format_value(key, value, data_type)
287
+ value = send("#{key}_default")
288
+ value = format_value(key, value, data_type)
301
289
  # lets set the variable with the updated value
302
- instance_variable_set ivar, value
303
- send will_change_method
290
+ instance_variable_set ivar, value
291
+ send will_change_method
304
292
  elsif value.nil? && data_type == :array
305
293
  value = Parse::CollectionProxy.new [], delegate: self, key: key
306
294
  instance_variable_set ivar, value
@@ -318,12 +306,12 @@ module Parse
318
306
  end
319
307
  # finally return the value
320
308
  if symbolize_value
321
- if data_type == :string
322
- return value.respond_to?(:to_sym) ? value.to_sym : value
323
- elsif data_type == :array && value.is_a?(Array)
324
- # value.map(&:to_sym)
325
- return value.compact.map { |m| m.respond_to?(:to_sym) ? m.to_sym : m }
326
- end
309
+ if data_type == :string
310
+ return value.respond_to?(:to_sym) ? value.to_sym : value
311
+ elsif data_type == :array && value.is_a?(Array)
312
+ # value.map(&:to_sym)
313
+ return value.compact.map { |m| m.respond_to?(:to_sym) ? m.to_sym : m }
314
+ end
327
315
  end
328
316
 
329
317
  value
@@ -338,7 +326,7 @@ module Parse
338
326
  # returns true if set to true, false otherwise
339
327
  define_method("#{key}?") { (send(key) == true) }
340
328
  unless opts[:scopes] == false
341
- scope key, ->(opts = {}){ query( opts.merge(key => true) ) }
329
+ scope key, ->(opts = {}) { query(opts.merge(key => true)) }
342
330
  end
343
331
  elsif data_type == :integer || data_type == :float
344
332
  if self.method_defined?("#{key}_increment!")
@@ -369,7 +357,6 @@ module Parse
369
357
  amount = -amount if amount > 0
370
358
  send("#{key}_increment!", amount)
371
359
  end
372
-
373
360
  end
374
361
 
375
362
  # The second method to be defined is a setter method. This is done by
@@ -393,7 +380,7 @@ module Parse
393
380
  # this will grab the current value and keep a copy of it - but we only do this if
394
381
  # the new value being set is different from the current value stored.
395
382
  if track == true
396
- send will_change_method unless val == instance_variable_get( ivar )
383
+ send will_change_method unless val == instance_variable_get(ivar)
397
384
  end
398
385
 
399
386
  if symbolize_value
@@ -435,7 +422,6 @@ module Parse
435
422
  end
436
423
  true
437
424
  end # property
438
-
439
425
  end #ClassMethods
440
426
 
441
427
  # @return [Hash] a hash mapping of all property fields and their types.
@@ -451,7 +437,7 @@ module Parse
451
437
  # TODO: We can optimize
452
438
  # @return [Hash] returns the list of property attributes for this class.
453
439
  def attributes
454
- {__type: :string, :className => :string}.merge!(self.class.attributes)
440
+ { __type: :string, :className => :string }.merge!(self.class.attributes)
455
441
  end
456
442
 
457
443
  # support for setting a hash of attributes on the object with a given dirty tracking value
@@ -466,7 +452,7 @@ module Parse
466
452
  @id ||= hash[Parse::Model::ID] || hash[Parse::Model::OBJECT_ID] || hash[:objectId]
467
453
  hash.each do |key, value|
468
454
  method = "#{key}_set_attribute!".freeze
469
- send(method, value, dirty_track) if respond_to?( method )
455
+ send(method, value, dirty_track) if respond_to?(method)
470
456
  end
471
457
  end
472
458
 
@@ -494,7 +480,7 @@ module Parse
494
480
  next unless fields[key].present?
495
481
  remote_field = self.field_map[key] || key
496
482
  h[remote_field] = send key
497
- h[remote_field] = {__op: :Delete} if h[remote_field].nil?
483
+ h[remote_field] = { __op: :Delete } if h[remote_field].nil?
498
484
  # in the case that the field is a Parse object, generate a pointer
499
485
  # if it is a Parse::PointerCollectionProxy, then make sure we get a list of pointers.
500
486
  h[remote_field] = h[remote_field].parse_pointers if h[remote_field].is_a?(Parse::PointerCollectionProxy)
@@ -509,6 +495,7 @@ module Parse
509
495
  fields[key.to_sym].present?
510
496
  end
511
497
  end
498
+
512
499
  # Returns a formatted value based on the operation hash and data_type of the property.
513
500
  # For some values in Parse, they are specified as operation hashes which could include
514
501
  # Add, Remove, Delete, AddUnique and Increment.
@@ -585,7 +572,7 @@ module Parse
585
572
  val = val.to_f unless val.blank?
586
573
  when :acl
587
574
  # ACL types go through a special conversion
588
- val = ACL.typecast(val, self)
575
+ val = ACL.typecast(val, self)
589
576
  when :date
590
577
  # if it respond to parse_date, then use that as the conversion.
591
578
  if val.respond_to?(:parse_date) && val.is_a?(Parse::Date) == false
@@ -596,9 +583,9 @@ module Parse
596
583
  elsif val.is_a?(String)
597
584
  # if it's a string, try parsing the date
598
585
  val = Parse::Date.parse val
599
- #elsif val.present?
600
- # pus "[Parse::Stack] Invalid date value '#{val}' assigned to #{self.class}##{key}, it should be a Parse::Date or DateTime."
601
- # raise ValueError, "Invalid date value '#{val}' assigned to #{self.class}##{key}, it should be a Parse::Date or DateTime."
586
+ #elsif val.present?
587
+ # pus "[Parse::Stack] Invalid date value '#{val}' assigned to #{self.class}##{key}, it should be a Parse::Date or DateTime."
588
+ # raise ValueError, "Invalid date value '#{val}' assigned to #{self.class}##{key}, it should be a Parse::Date or DateTime."
602
589
  end
603
590
  when :timezone
604
591
  val = Parse::TimeZone.new(val) if val.present?
@@ -613,7 +600,5 @@ module Parse
613
600
  end
614
601
  val
615
602
  end
616
-
617
603
  end # Properties
618
-
619
604
  end # Parse