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 +4 -1
- data/lib/Parsistence/Model.rb +86 -10
- data/lib/Parsistence/Query.rb +97 -3
- data/lib/Parsistence/User.rb +16 -0
- data/lib/Parsistence/version.rb +1 -1
- metadata +20 -39
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
|
|
data/lib/Parsistence/Model.rb
CHANGED
@@ -18,7 +18,7 @@ module Parsistence
|
|
18
18
|
method = method.to_sym
|
19
19
|
setter = false
|
20
20
|
|
21
|
-
if
|
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
|
-
|
66
|
-
|
67
|
-
|
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
|
-
|
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
|
-
|
359
|
+
end
|
284
360
|
|
285
361
|
def self.included(base)
|
286
362
|
base.extend(ClassMethods)
|
data/lib/Parsistence/Query.rb
CHANGED
@@ -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
|
-
|
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
|
-
#
|
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
|
-
#
|
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
|
data/lib/Parsistence/User.rb
CHANGED
@@ -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
|
|
data/lib/Parsistence/version.rb
CHANGED
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
|
-
|
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
|
-
|
60
|
-
|
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
|
-
|
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.
|
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:
|