Parsistence 0.3.7 → 0.3.9

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