Parsistence 0.3.7 → 0.3.9

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.
data/README.md CHANGED
@@ -20,13 +20,16 @@ Create an instance:
20
20
 
21
21
  ```ruby
22
22
  p = Post.new
23
+
24
+ p.respond_to?(:title) #=> true
25
+
23
26
  p.title = "Why RubyMotion Is Better Than Objective-C"
24
27
  p.author = "Josh Symonds"
25
28
  p.body = "trololol"
26
29
  p.saveEventually
27
30
  ```
28
31
 
29
- `Parsistence::Model` objects will `respond_to?` to all methods available to [`PFObject`](https://parse.com/docs/ios/api/Classes/PFObject.html) in the Parse iOS SDK. You can also access the `PFObject` instance directly with, you guessed it, `Parsistence::Model#PFObject`.
32
+ `Parsistence::Model` objects will `respond_to?` to all methods available to [`PFObject`](https://parse.com/docs/ios/api/Classes/PFObject.html) in the Parse iOS SDK, as well as 'fields' getters and setters. You can also access the `PFObject` instance directly with, you guessed it, `Parsistence::Model#PFObject`.
30
33
 
31
34
  ### Users
32
35
 
@@ -18,7 +18,7 @@ module Parsistence
18
18
  method = method.to_sym
19
19
  setter = false
20
20
 
21
- if method.to_s.include?("=")
21
+ if setter?(method)
22
22
  setter = true
23
23
  method = method.split("=")[0].to_sym
24
24
  end
@@ -45,7 +45,31 @@ module Parsistence
45
45
  super
46
46
  end
47
47
  end
48
-
48
+
49
+ def getter?(method)
50
+ !setter?(method)
51
+ end
52
+
53
+ def setter?(method)
54
+ method.to_s.include?("=")
55
+ end
56
+
57
+ # Override of ruby's respond_to?
58
+ #
59
+ # @param [Symbol] method
60
+ # @return [Bool] true/false
61
+ def respond_to?(method)
62
+ if setter?(method)
63
+ method = method.to_s.split("=")[0]
64
+ end
65
+
66
+ method = method.to_sym unless method.is_a? Symbol
67
+
68
+ return true if fields.include?(method) || relations.include?(method)
69
+
70
+ super
71
+ end
72
+
49
73
  def fields
50
74
  self.class.send(:get_fields)
51
75
  end
@@ -62,9 +86,13 @@ module Parsistence
62
86
  end
63
87
 
64
88
  def setField(field, value)
65
- return @PFObject.send("#{field}=", value) if RESERVED_KEYS.include?(field)
66
- return @PFObject[field] = value if fields.include? field.to_sym
67
- raise "Parsistence Exception: Invalid field name #{field} for object #{self.class.to_s}" unless fields.include? field.to_sym
89
+ if RESERVED_KEYS.include?(field) || fields.include?(field.to_sym)
90
+ return @PFObject.removeObjectForKey(field.to_s) if value.nil?
91
+ return @PFObject.send("#{field}=", value) if RESERVED_KEYS.include?(field)
92
+ return @PFObject[field] = value
93
+ else
94
+ raise "Parsistence Exception: Invalid field name #{field} for object #{self.class.to_s}"
95
+ end
68
96
  end
69
97
 
70
98
  def getRelation(field)
@@ -97,6 +125,9 @@ module Parsistence
97
125
  raise "Parsistence Exception: Invalid relation name #{field} for object #{self.class.to_s}"
98
126
  end
99
127
 
128
+ # Returns all of the attributes of the Model
129
+ #
130
+ # @return [Hash] attributes of Model
100
131
  def attributes
101
132
  attributes = {}
102
133
  fields.each do |f|
@@ -105,6 +136,11 @@ module Parsistence
105
136
  @attributes = attributes
106
137
  end
107
138
 
139
+ # Sets the attributes of the Model
140
+ #
141
+ # @param [Hash] of attribute, values to set on the Model
142
+ # @return [Hash] that you gave it
143
+ # @note will throw an error if a key is invalid
108
144
  def attributes=(hashValue)
109
145
  hashValue.each do |k, v|
110
146
  if v.respond_to?(:each) && !v.is_a?(PFObject)
@@ -117,13 +153,17 @@ module Parsistence
117
153
  end
118
154
  end
119
155
 
156
+ # Save the current state of the Model to Parse
157
+ #
158
+ # @note calls before/after_save hooks
159
+ # @note before_save MUST return true, or save will not be called on PFObject
160
+ # @note does not save if validations fail
161
+ #
162
+ # @return [Bool] true/false
120
163
  def save
121
164
  saved = false
122
165
  unless before_save == false
123
- reset_errors
124
- self.attributes.each do |field, value|
125
- validateField field, value
126
- end
166
+ self.validate
127
167
 
128
168
  if @errors && @errors.length > 0
129
169
  saved = false
@@ -138,6 +178,22 @@ module Parsistence
138
178
  def before_save; end
139
179
  def after_save; end
140
180
 
181
+ def validate
182
+ reset_errors
183
+ self.attributes.each do |field, value|
184
+ validateField field, value
185
+ end
186
+ end
187
+
188
+ # Checks to see if the current Model has errors
189
+ #
190
+ # @return [Bool] true/false
191
+ def is_valid?
192
+ self.validate
193
+ return false if @errors && @errors.length > 0
194
+ true
195
+ end
196
+
141
197
  def delete
142
198
  deleted = false
143
199
  unless before_delete == false
@@ -200,10 +256,19 @@ module Parsistence
200
256
  end
201
257
 
202
258
  module ClassMethods
259
+
260
+ # set the fields for the current Model
261
+ # used in method_missing
262
+ #
263
+ # @param [Symbol] one or more fields
203
264
  def fields(*args)
204
265
  args.each {|arg| field(arg)}
205
266
  end
206
267
 
268
+ # set a field for the current Model
269
+ #
270
+ # @param [Symbol] field
271
+ # (see #fields)
207
272
  def field(name)
208
273
  @fields ||= [:objectId]
209
274
  @fields << name.to_sym
@@ -214,10 +279,18 @@ module Parsistence
214
279
  @fields ||= []
215
280
  end
216
281
 
282
+ # set the relations for the current Model
283
+ # used in method_missing
284
+ #
285
+ # @param [Symbol] one or more relations
217
286
  def relations(*args)
218
287
  args.each { |arg| relation(arg)}
219
288
  end
220
289
 
290
+ # set a relation for the current Model
291
+ #
292
+ # @param [Symbol] relation
293
+ # (see #relations)
221
294
  def relation(name)
222
295
  @relations ||= []
223
296
  @relations << name.to_sym
@@ -262,6 +335,9 @@ module Parsistence
262
335
  @belongs_to_attributes[field] ||= { class_name: field }
263
336
  end
264
337
 
338
+ # require a certain field to be present (not nil And not an empty String)
339
+ #
340
+ # @param [Symbol, Hash] field and options (now only has message)
265
341
  def validates_presence_of(field, opts={})
266
342
  @presenceValidationMessages ||= {}
267
343
  @presenceValidationMessages[field] = opts[:message] if opts[:message]
@@ -280,7 +356,7 @@ module Parsistence
280
356
  @presenceValidations ||= []
281
357
  @presenceValidations << field
282
358
  end
283
- end
359
+ end
284
360
 
285
361
  def self.included(base)
286
362
  base.extend(ClassMethods)
@@ -65,42 +65,62 @@ module Parsistence
65
65
  @includes = []
66
66
  end
67
67
 
68
+ def checkKey(key)
69
+ # Sanity check for mis-entered keys.
70
+ tmp = self.klass.new
71
+ unless tmp.respond_to?(key.to_sym)
72
+ $stderr.puts "Parsistence Warning: No field '#{key}' found for #{self.klass.to_s} query."
73
+ end
74
+ end
75
+
68
76
  def createQuery
69
- query = PFQuery.queryWithClassName(self.klass.to_s)
77
+ if self.klass.to_s == "User"
78
+ query = PFUser.query
79
+ else
80
+ query = PFQuery.queryWithClassName(self.klass.to_s)
81
+ end
70
82
  @includes.each do |include|
71
83
  query.includeKey(include)
72
84
  end
73
85
 
74
86
  @conditions.each do |key, value|
87
+ checkKey key
75
88
  value = value.PFObject if value.respond_to?(:PFObject)
76
89
  query.whereKey(key, equalTo: value)
77
90
  end
78
91
  @inConditions.each do |key, value|
92
+ checkKey key
79
93
  value = value.PFObject if value.respond_to?(:PFObject)
80
94
  query.whereKey(key, containedIn: value)
81
95
  end
82
96
  @negativeConditions.each do |key, value|
97
+ checkKey key
83
98
  value = value.PFObject if value.respond_to?(:PFObject)
84
99
  query.whereKey(key, notEqualTo: value)
85
100
  end
86
101
  @ltConditions.each do |key, value|
102
+ checkKey key
87
103
  value = value.PFObject if value.respond_to?(:PFObject)
88
104
  query.whereKey(key, lessThan: value)
89
105
  end
90
106
  @gtConditions.each do |key, value|
107
+ checkKey key
91
108
  value = value.PFObject if value.respond_to?(:PFObject)
92
109
  query.whereKey(key, greaterThan: value)
93
110
  end
94
111
  @lteConditions.each do |key, value|
112
+ checkKey key
95
113
  value = value.PFObject if value.respond_to?(:PFObject)
96
114
  query.whereKey(key, lessThanOrEqualTo: value)
97
115
  end
98
116
  @gteConditions.each do |key, value|
117
+ checkKey key
99
118
  value = value.PFObject if value.respond_to?(:PFObject)
100
119
  query.whereKey(key, greaterThanOrEqualTo: value)
101
120
  end
102
121
  first = true
103
122
  @order.each do |field, direction|
123
+ checkKey field
104
124
  if first
105
125
  query.orderByAscending(field) if direction && direction == :asc
106
126
  query.orderByDescending(field) if direction && direction == :desc
@@ -117,6 +137,16 @@ module Parsistence
117
137
  query
118
138
  end
119
139
 
140
+ # TODO: Get this working.
141
+ # def count(&callback)
142
+ # query = createQuery
143
+
144
+ # myKlass = self.klass
145
+ # query.countObjectsInBackgroundWithBlock (lambda { |item_count, error|
146
+ # callback.call item_count, error
147
+ # })
148
+ # end
149
+
120
150
  def fetch(&callback)
121
151
  if @limit && @limit == 1
122
152
  fetchOne(&callback)
@@ -127,6 +157,13 @@ module Parsistence
127
157
  self
128
158
  end
129
159
 
160
+ # @deprecated
161
+ # Grab all results that match query
162
+ #
163
+ # @param [Block] callback block
164
+ # @return [Nil]
165
+ #
166
+ # (see #all)
130
167
  def fetchAll(&callback)
131
168
  query = createQuery
132
169
 
@@ -137,6 +174,13 @@ module Parsistence
137
174
  })
138
175
  end
139
176
 
177
+ # @deprecated
178
+ # Grab first result that matches query
179
+ #
180
+ # @param [Block] callback block
181
+ # @return [Nil]
182
+ #
183
+ # (see #first)
140
184
  def fetchOne(&callback)
141
185
  limit(0, 1)
142
186
  query = createQuery
@@ -148,23 +192,33 @@ module Parsistence
148
192
  })
149
193
  end
150
194
 
151
- # Query methods
195
+ # @deprecated
196
+ # (see #eq)
152
197
  def where(*conditions, &callback)
153
198
  eq(conditions.first)
154
199
  fetch(&callback)
155
200
  nil
156
201
  end
157
202
 
203
+ # Grab all results that match query
204
+ #
205
+ # @param [Block] callback block
206
+ # @return [Nil]
158
207
  def all(&callback)
159
208
  fetchAll(&callback)
160
209
  nil
161
210
  end
162
211
 
212
+ # Grab first result that matches query
213
+ #
214
+ # @param [Block] callback block
215
+ # @return [Nil]
163
216
  def first(&callback)
164
217
  fetchOne(&callback)
165
218
  nil
166
219
  end
167
220
 
221
+ # Prints current Query conditions to STDERR
168
222
  def showQuery
169
223
  $stderr.puts "Conditions: #{@conditions.to_s}"
170
224
  $stderr.puts "negativeConditions: #{@negativeConditions.to_s}"
@@ -178,7 +232,11 @@ module Parsistence
178
232
  $stderr.puts "offset: #{@offset.to_s}"
179
233
  end
180
234
 
181
- # Query parameter methods
235
+ # Limit number of results
236
+ #
237
+ # @param [Integer] offset
238
+ # @param [Integer] number to limit, if not passed, first arg is used for limit
239
+ # @return [Object] self
182
240
  def limit(offset, number = nil)
183
241
  if number.nil?
184
242
  number = offset
@@ -189,6 +247,10 @@ module Parsistence
189
247
  self
190
248
  end
191
249
 
250
+ # Order query results
251
+ #
252
+ # @param [Hash] of field - order-direction
253
+ # @return [Object] self
192
254
  def order(*fields)
193
255
  fields.each do |field|
194
256
  @order.merge! field
@@ -196,6 +258,10 @@ module Parsistence
196
258
  self
197
259
  end
198
260
 
261
+ # Query for fields where key == value
262
+ #
263
+ # @param [Hash] of key-value pairs
264
+ # @return [Object] self
199
265
  def eq(*fields)
200
266
  fields.each do |field|
201
267
  @conditions.merge! field
@@ -203,6 +269,10 @@ module Parsistence
203
269
  self
204
270
  end
205
271
 
272
+ # Query for fields where key != value
273
+ #
274
+ # @param [Hash] of key-value pairs
275
+ # @return [Object] self
206
276
  def notEq(*fields)
207
277
  fields.each do |field|
208
278
  @negativeConditions.merge! field
@@ -210,6 +280,10 @@ module Parsistence
210
280
  self
211
281
  end
212
282
 
283
+ # Query for fields where key < value
284
+ #
285
+ # @param [Hash] of key-value pairs
286
+ # @return [Object] self
213
287
  def lt(*fields)
214
288
  fields.each do |field|
215
289
  @ltConditions.merge! field
@@ -217,6 +291,10 @@ module Parsistence
217
291
  self
218
292
  end
219
293
 
294
+ # Query for fields where key > value
295
+ #
296
+ # @param [Hash] of key-value pairs
297
+ # @return [Object] self
220
298
  def gt(*fields)
221
299
  fields.each do |field|
222
300
  @gtConditions.merge! field
@@ -224,6 +302,10 @@ module Parsistence
224
302
  self
225
303
  end
226
304
 
305
+ # Query for fields where key is in an array of values
306
+ #
307
+ # @param [Hash] of key-value pairs, value is an array
308
+ # @return [Object] self
227
309
  def in(*fields)
228
310
  fields.each do |field|
229
311
  @inConditions.merge! field
@@ -231,6 +313,10 @@ module Parsistence
231
313
  self
232
314
  end
233
315
 
316
+ # Query for fields where key <= value
317
+ #
318
+ # @param [Hash] of key-value pairs
319
+ # @return [Object] self
234
320
  def lte(*fields)
235
321
  fields.each do |field|
236
322
  @lteConditions.merge! field
@@ -238,6 +324,10 @@ module Parsistence
238
324
  self
239
325
  end
240
326
 
327
+ # Query for fields where key >= value
328
+ #
329
+ # @param [Hash] of key-value pairs
330
+ # @return [Object] self
241
331
  def gte(*fields)
242
332
  fields.each do |field|
243
333
  @gteConditions.merge! field
@@ -245,6 +335,10 @@ module Parsistence
245
335
  self
246
336
  end
247
337
 
338
+ # Include related object in query
339
+ #
340
+ # @param [Hash] of symbols
341
+ # @return [Object] self
248
342
  def includes(*fields)
249
343
  fields.each do |field|
250
344
  @includes << field
@@ -29,6 +29,22 @@ module Parsistence
29
29
  self.PFUser.password = value
30
30
  end
31
31
 
32
+ def signUp
33
+ saved = false
34
+ unless before_save == false
35
+ self.validate
36
+
37
+ if @errors && @errors.length > 0
38
+ saved = false
39
+ else
40
+ saved = @PFObject.signUp
41
+ end
42
+
43
+ after_save if saved
44
+ end
45
+ saved
46
+ end
47
+
32
48
  module ClassMethods
33
49
  include Parsistence::Model::ClassMethods
34
50
 
@@ -1,3 +1,3 @@
1
1
  module Parsistence
2
- VERSION = "0.3.7"
2
+ VERSION = "0.3.9" unless defined? Parsistence::VERSION
3
3
  end
metadata CHANGED
@@ -1,37 +1,27 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: Parsistence
3
- version: !ruby/object:Gem::Version
4
- hash: 29
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.9
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 3
9
- - 7
10
- version: 0.3.7
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Jamon Holmgren
14
9
  - Silas J. Matson
15
10
  - Alan deLevie
16
11
  autorequire:
17
12
  bindir: bin
18
13
  cert_chain: []
19
-
20
- date: 2012-10-11 00:00:00 Z
14
+ date: 2012-10-24 00:00:00.000000000 Z
21
15
  dependencies: []
22
-
23
16
  description: Your models on RubyMotion and Parse in a persistence.js style pattern.
24
- email:
17
+ email:
25
18
  - jamon@clearsightstudio.com
26
19
  - silas@clearsightstudio.com
27
20
  - adelevie@gmail.com
28
21
  executables: []
29
-
30
22
  extensions: []
31
-
32
23
  extra_rdoc_files: []
33
-
34
- files:
24
+ files:
35
25
  - .gitignore
36
26
  - Gemfile
37
27
  - Parsistence.gemspec
@@ -45,36 +35,27 @@ files:
45
35
  - lib/Parsistence/version.rb
46
36
  homepage: https://github.com/clearsightstudio/Parsistence
47
37
  licenses: []
48
-
49
38
  post_install_message:
50
39
  rdoc_options: []
51
-
52
- require_paths:
40
+ require_paths:
53
41
  - lib
54
- required_ruby_version: !ruby/object:Gem::Requirement
42
+ required_ruby_version: !ruby/object:Gem::Requirement
55
43
  none: false
56
- requirements:
57
- - - ">="
58
- - !ruby/object:Gem::Version
59
- hash: 3
60
- segments:
61
- - 0
62
- version: "0"
63
- required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
49
  none: false
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- hash: 3
69
- segments:
70
- - 0
71
- version: "0"
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
72
54
  requirements: []
73
-
74
55
  rubyforge_project: Parsistence
75
- rubygems_version: 1.8.24
56
+ rubygems_version: 1.8.22
76
57
  signing_key:
77
58
  specification_version: 3
78
59
  summary: Your models on RubyMotion and Parse in a persistence.js style pattern.
79
60
  test_files: []
80
-
61
+ has_rdoc: