parsecom 0.1.0 → 0.2.0
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 +268 -28
- data/lib/parse/acl.rb +40 -0
- data/lib/parse/client.rb +12 -0
- data/lib/parse/object.rb +5 -0
- data/lib/parse/op/add_relation.rb +7 -1
- data/lib/parse/pointer.rb +10 -2
- data/lib/parse/relation.rb +46 -0
- data/lib/parse/role.rb +45 -1
- data/lib/parse/user.rb +4 -0
- data/lib/parse/version.rb +1 -1
- data/lib/parsecom.rb +1 -0
- data/spec/fixtures/vcr_cassettes/user_find.yml +1 -1
- metadata +3 -2
data/README.md
CHANGED
@@ -2,6 +2,41 @@
|
|
2
2
|
|
3
3
|
Yet-Another Parse.com Library written in Pure Ruby
|
4
4
|
|
5
|
+
**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*
|
6
|
+
|
7
|
+
- [Parsecom](#parsecom)
|
8
|
+
- [Usage](#usage)
|
9
|
+
- [Preparing](#preparing)
|
10
|
+
- [Declaring Parse Classes](#declaring-parse-classes)
|
11
|
+
- [Objects](#objects)
|
12
|
+
- [Creating Objects](#creating-objects)
|
13
|
+
- [Retrieving Objects](#retrieving-objects)
|
14
|
+
- [Updating Objects](#updating-objects)
|
15
|
+
- [Counters](#counters)
|
16
|
+
- [Arrays](#arrays)
|
17
|
+
- [Relations](#relations)
|
18
|
+
- [Deleting Objects](#deleting-objects)
|
19
|
+
- [Batch Operations](#batch-operations)
|
20
|
+
- [Queries](#queries)
|
21
|
+
- [Basic Queries](#basic-queries)
|
22
|
+
- [Query Constraints](#query-constraints)
|
23
|
+
- [Queries on Array Values](#queries-on-array-values)
|
24
|
+
- [Relational Queries](#relational-queries)
|
25
|
+
- [Counting Objects](#counting-objects)
|
26
|
+
- [Compound Queries](#compound-queries)
|
27
|
+
- [Users](#users)
|
28
|
+
- [Sign up](#sign-up)
|
29
|
+
- [Log in](#log-in)
|
30
|
+
- [Requesting A Password Reset](#requesting-a-password-reset)
|
31
|
+
- [Retrieving Users](#retrieving-users)
|
32
|
+
- [Updating Users](#updating-users)
|
33
|
+
- [Querying](#querying)
|
34
|
+
- [Deleting Users](#deleting-users)
|
35
|
+
- [Linking Users](#linking-users)
|
36
|
+
- [Roles](#roles)
|
37
|
+
- [Creating Roles](#creating-roles)
|
38
|
+
- [Security](#security)
|
39
|
+
|
5
40
|
## Usage
|
6
41
|
|
7
42
|
### Preparing
|
@@ -63,9 +98,11 @@ Parse::Object.create :GameScore
|
|
63
98
|
|
64
99
|
It may be suitable for writing code in declarative style.
|
65
100
|
|
66
|
-
###
|
101
|
+
### Objects
|
102
|
+
|
103
|
+
#### Creating Objects
|
67
104
|
|
68
|
-
To create new parse object,
|
105
|
+
To create new parse object, just new and save the object.
|
69
106
|
|
70
107
|
```ruby
|
71
108
|
game_score = GameScore.new
|
@@ -78,7 +115,7 @@ game_score.new? # => false
|
|
78
115
|
game_score.parse_object_id # => 'Ed1nuqPvcm'
|
79
116
|
```
|
80
117
|
|
81
|
-
|
118
|
+
#### Retrieving Objects
|
82
119
|
|
83
120
|
There are two ways to retrieve objects. One is using Query objects directly and
|
84
121
|
another is using Parse::Object as a facade of a query object.
|
@@ -95,30 +132,15 @@ results = GameScore.find :where => {:objectId => 'Ed1nuqPvcm'}
|
|
95
132
|
result = GameScore.find_by_id 'Ed1nuqPvcm'
|
96
133
|
```
|
97
134
|
|
98
|
-
|
135
|
+
To fetch a child object, you can use the :include parameter.
|
99
136
|
|
100
137
|
```ruby
|
101
|
-
|
102
|
-
results = Parse::Query.new(GameScore).
|
103
|
-
limit(10).
|
104
|
-
order(score).
|
105
|
-
where do
|
106
|
-
column(:score).gte(1000).lte(3000)
|
107
|
-
column(:cheatMode).eq(false)
|
108
|
-
end.
|
109
|
-
invoke
|
110
|
-
|
111
|
-
# using Query object through Parse::Object
|
112
|
-
results = GameScore.find :limit => 10, :order => 'score',
|
113
|
-
:where => proc{
|
114
|
-
column(:score).gte(1000).lte(3000)
|
115
|
-
column(:cheatMode).eq(false)
|
116
|
-
}
|
138
|
+
results = GameScore.find :where => {:objectId => 'Ed1nuqPvcm'}, :include => 'game'
|
117
139
|
```
|
118
140
|
|
119
141
|
To know more about retrieving objects, see spec/parse_query_spec.rb
|
120
142
|
|
121
|
-
|
143
|
+
#### Updating Objects
|
122
144
|
|
123
145
|
To update attributes, just update the attribute and save.
|
124
146
|
|
@@ -135,7 +157,7 @@ the Parse::Client object for it.
|
|
135
157
|
Parse::Client.default.update :GaemScore, 'Ed1nuqPvcm', :score => 73453
|
136
158
|
```
|
137
159
|
|
138
|
-
|
160
|
+
##### Counters
|
139
161
|
|
140
162
|
```ruby
|
141
163
|
game_score = GameScore.find_by_id 'Ed1nuqPvcm'
|
@@ -143,7 +165,7 @@ game_score.score = Parse::Op::Increment.new 1
|
|
143
165
|
game_score.save
|
144
166
|
```
|
145
167
|
|
146
|
-
|
168
|
+
##### Arrays
|
147
169
|
|
148
170
|
```ruby
|
149
171
|
game_score = GameScore.find_by_id 'Ed1nuqPvcm'
|
@@ -151,7 +173,7 @@ game_score.skils = Parse::Op::AddUnique.new 'flying', 'kungfu'
|
|
151
173
|
game_score.save
|
152
174
|
```
|
153
175
|
|
154
|
-
|
176
|
+
##### Relations
|
155
177
|
|
156
178
|
```ruby
|
157
179
|
game_score = GameScore.find_by_id 'Ed1nuqPvcm'
|
@@ -165,7 +187,7 @@ game_score.opponents = Parse::Op::RemoveRelation.new player.pointer
|
|
165
187
|
game_score.save
|
166
188
|
```
|
167
189
|
|
168
|
-
|
190
|
+
#### Deleting Objects
|
169
191
|
|
170
192
|
```ruby
|
171
193
|
game_score = GameScore.find_by_id 'Ed1nuqPvcm'
|
@@ -178,7 +200,7 @@ game_score.opponents = Parse::Op::Delete.new
|
|
178
200
|
game_score.save
|
179
201
|
```
|
180
202
|
|
181
|
-
|
203
|
+
#### Batch Operations
|
182
204
|
|
183
205
|
```ruby
|
184
206
|
seans_score = GameScore.new 'score' => 1337, 'playerName' => 'Sean Plott'
|
@@ -191,18 +213,236 @@ end
|
|
191
213
|
result = batch.run
|
192
214
|
```
|
193
215
|
|
194
|
-
###
|
216
|
+
### Queries
|
217
|
+
|
218
|
+
#### Basic Queries
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
game_scores = GameScore.find :all
|
222
|
+
```
|
223
|
+
|
224
|
+
#### Query Constraints
|
225
|
+
|
226
|
+
```ruby
|
227
|
+
game_scores = GameScore.find :where => {"playerName" => "Sean Plott", "cheatMode" => false}
|
228
|
+
```
|
229
|
+
|
230
|
+
```ruby
|
231
|
+
game_scores = GameScore.find :where => proc {
|
232
|
+
column(:score).gte(1000).lte(3000)
|
233
|
+
}
|
234
|
+
```
|
235
|
+
|
236
|
+
```ruby
|
237
|
+
game_scores = GameScore.find :where => proc {
|
238
|
+
column(:score).in(1, 3, 5, 7, 9)
|
239
|
+
}
|
240
|
+
```
|
241
|
+
|
242
|
+
```ruby
|
243
|
+
game_scores = GameScore.find :where => proc {
|
244
|
+
column(:playerName).nin("Jonathan Walsh", "Dario Wunsch", "Shawn Simon")
|
245
|
+
}
|
246
|
+
```
|
247
|
+
|
248
|
+
```ruby
|
249
|
+
game_scores = GameScore.find :where => proc {
|
250
|
+
column(:score).exists
|
251
|
+
}
|
252
|
+
```
|
253
|
+
|
254
|
+
```ruby
|
255
|
+
game_scores = GameScore.find :where => proc {
|
256
|
+
column(:score).exists(false)
|
257
|
+
}
|
258
|
+
```
|
259
|
+
|
260
|
+
```ruby
|
261
|
+
game_scores = GameScore.find :where => proc {
|
262
|
+
subquery = subquery_for :Team
|
263
|
+
subquery.where {column(:winPct).gt(0.5)}
|
264
|
+
subquery.key = 'city'
|
265
|
+
column(:hometown).select(subquery)
|
266
|
+
}
|
267
|
+
```
|
268
|
+
|
269
|
+
```ruby
|
270
|
+
game_scores = GameScore.find :order => 'score'
|
271
|
+
```
|
272
|
+
|
273
|
+
```ruby
|
274
|
+
game_scores = GameScore.find :order => '-score'
|
275
|
+
game_scores = GameScore.find :order_desc => 'score'
|
276
|
+
```
|
277
|
+
|
278
|
+
```ruby
|
279
|
+
game_scores = GameScore.find :order => ['score', '-name']
|
280
|
+
```
|
281
|
+
|
282
|
+
```ruby
|
283
|
+
game_scores = GameScore.find :limit => 200, :skip => 400
|
284
|
+
```
|
285
|
+
|
286
|
+
```ruby
|
287
|
+
game_scores = GameScore.find :keys => ['score', 'playerName']
|
288
|
+
```
|
289
|
+
|
290
|
+
#### Queries on Array Values
|
291
|
+
|
292
|
+
```ruby
|
293
|
+
game_scores = GameScore.find :where => proc {
|
294
|
+
column(:arrayKey).contains(2)
|
295
|
+
}
|
296
|
+
```
|
297
|
+
|
298
|
+
```ruby
|
299
|
+
game_scores = GameScore.find :where => proc {
|
300
|
+
column(:arrayKey).all(2, 3, 4)
|
301
|
+
}
|
302
|
+
```
|
303
|
+
|
304
|
+
#### Relational Queries
|
305
|
+
|
306
|
+
```ruby
|
307
|
+
game_scores = GameScore.find :where => proc {
|
308
|
+
post = Parse::Object(:Post).new :objectId => '8TOXdXf3tz'
|
309
|
+
column(:post).eq(post)
|
310
|
+
}
|
311
|
+
```
|
312
|
+
|
313
|
+
```ruby
|
314
|
+
game_scores = GameScore.find :where => proc {
|
315
|
+
subquery = subquery_for :Post
|
316
|
+
subquery.where do
|
317
|
+
column(:image).exists(true)
|
318
|
+
end
|
319
|
+
column(:post).in_query(subquery)
|
320
|
+
}
|
321
|
+
```
|
322
|
+
|
323
|
+
```ruby
|
324
|
+
game_scores = GameScore.find :where => proc {
|
325
|
+
pointer = Parse::Pointer.new('className' => 'Post', 'objectId' => '8TOXdXf3tz')
|
326
|
+
related_to :likes, pointer
|
327
|
+
}
|
328
|
+
```
|
329
|
+
|
330
|
+
#### Counting Objects
|
331
|
+
|
332
|
+
TBD
|
333
|
+
|
334
|
+
#### Compound Queries
|
335
|
+
|
336
|
+
```ruby
|
337
|
+
game_scores = GameScore.find :where => proc {
|
338
|
+
or_condition column(:wins).gt(150), column(:wins).lt(5)
|
339
|
+
}
|
340
|
+
```
|
341
|
+
|
342
|
+
### Users
|
343
|
+
|
344
|
+
#### Sign up
|
195
345
|
|
196
346
|
```ruby
|
197
347
|
user = Parse::User.sign_up 'YOUR USERNAME', 'YOUR PASSWORD'
|
198
348
|
```
|
199
349
|
|
200
|
-
|
350
|
+
#### Log in
|
201
351
|
|
202
352
|
```ruby
|
203
353
|
user = Parse::User.log_in 'YOUR USERNAME', 'YOUR PASSWORD'
|
204
354
|
```
|
205
355
|
|
356
|
+
#### Requesting A Password Reset
|
357
|
+
|
358
|
+
```ruby
|
359
|
+
Parse::User.request_password_reset 'your@email.address'
|
360
|
+
```
|
361
|
+
|
362
|
+
#### Retrieving Users
|
363
|
+
|
364
|
+
```ruby
|
365
|
+
user = Parse::User.find_by_id :g7y9tkhB7O
|
366
|
+
```
|
367
|
+
|
368
|
+
#### Updating Users
|
369
|
+
|
370
|
+
```ruby
|
371
|
+
user = Parse::User.find_by_id :g7y9tkhB7O
|
372
|
+
user.phone = '415-369-6201'
|
373
|
+
user.save
|
374
|
+
```
|
375
|
+
|
376
|
+
#### Querying
|
377
|
+
|
378
|
+
```ruby
|
379
|
+
users = Parse::User.find :all
|
380
|
+
```
|
381
|
+
|
382
|
+
#### Deleting Users
|
383
|
+
|
384
|
+
```ruby
|
385
|
+
user = Parse::User.find_by_id :g7y9tkhB7O
|
386
|
+
user.delete
|
387
|
+
```
|
388
|
+
|
389
|
+
#### Linking Users
|
390
|
+
|
391
|
+
TBD
|
392
|
+
|
393
|
+
### Roles
|
394
|
+
|
395
|
+
#### Creating Roles
|
396
|
+
|
397
|
+
```ruby
|
398
|
+
moderator = Parse::Role.new 'name' => 'Moderators', 'ACL' => Parse::ACL::PUBLIC_READ_ONLY
|
399
|
+
moderator.save
|
400
|
+
```
|
401
|
+
|
402
|
+
```ruby
|
403
|
+
moderator = Parse::Role.new 'name' => 'Moderators', 'ACL' => Parse::ACL::PUBLIC_READ_ONLY
|
404
|
+
moderator.roles.add Parse::Role.new('objectId' => 'Ed1nuqPvc')
|
405
|
+
moderator.users.add Parse::User.new('objectId' => '8TOXdXf3tz')
|
406
|
+
moderator.save
|
407
|
+
```
|
408
|
+
|
409
|
+
#### Retrieving Roles
|
410
|
+
|
411
|
+
```ruby
|
412
|
+
role = Parse::Role.find_by_id 'mrmBZvsErB'
|
413
|
+
role.name # => 'Moderators'
|
414
|
+
role.ACL.readable? '*' # => true
|
415
|
+
role.ACL.writable? 'role:Administrators' # => true
|
416
|
+
```
|
417
|
+
|
418
|
+
#### Updating Roles
|
419
|
+
|
420
|
+
```ruby
|
421
|
+
user1 = Parse::User.new 'objectId' => '8TOXdXf3tz'
|
422
|
+
user2 = Parse::User.new 'objectId' => 'g7y9tkhB7O'
|
423
|
+
role = Parse::Role.find_by_id 'mrmBZvsErB'
|
424
|
+
role.users = Parse::Op::AddRelation.new user1.pointer, user2.pointer
|
425
|
+
role.save
|
426
|
+
```
|
427
|
+
|
428
|
+
```ruby
|
429
|
+
removed_role = Parse::Role.new 'objectId' => 'Ed1nuqPvc'
|
430
|
+
role = Parse::Role.find_by_id 'mrmBZvsErB'
|
431
|
+
role.roles = Parse::Op::RemoveRelation.new removed_role
|
432
|
+
role.save
|
433
|
+
```
|
434
|
+
|
435
|
+
#### Deleting Roles
|
436
|
+
|
437
|
+
```ruby
|
438
|
+
role = Parse::Role.find_by_id 'mrmBZvsErB'
|
439
|
+
role.delete
|
440
|
+
```
|
441
|
+
|
442
|
+
### Files
|
443
|
+
|
444
|
+
TBD
|
445
|
+
|
206
446
|
### Security
|
207
447
|
|
208
448
|
If you add an exclamation mark, "!" after the method name, the method is executed by using the master key.
|
data/lib/parse/acl.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# coding:utf-8
|
2
|
+
module Parse
|
3
|
+
class ACL
|
4
|
+
READ_ONLY = {'read' => true}
|
5
|
+
WRITE_ONLY = {'write' => true}
|
6
|
+
READ_WRITE = {'read' => true, 'write' => true}
|
7
|
+
NONE = {}
|
8
|
+
PUBLIC = '*'
|
9
|
+
|
10
|
+
def initialize hash={}, &block
|
11
|
+
@acl = hash.dup
|
12
|
+
tap &block if block
|
13
|
+
end
|
14
|
+
|
15
|
+
def readable user
|
16
|
+
(@acl[user] ||= {})['read'] = true
|
17
|
+
end
|
18
|
+
|
19
|
+
def readable? user
|
20
|
+
!!(@acl[user] ||= {})['read']
|
21
|
+
end
|
22
|
+
|
23
|
+
def writable user
|
24
|
+
(@acl[user] ||= {})['write'] = true
|
25
|
+
end
|
26
|
+
|
27
|
+
def writable? user
|
28
|
+
!!(@acl[user] ||= {})['write']
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_json *args
|
32
|
+
@acl.to_json
|
33
|
+
end
|
34
|
+
|
35
|
+
PUBLIC_READ_ONLY = self.new PUBLIC => READ_ONLY
|
36
|
+
PUBLIC_WRITE_ONLY = self.new PUBLIC => WRITE_ONLY
|
37
|
+
PUBLIC_READ_WRITE = self.new PUBLIC => READ_WRITE
|
38
|
+
PUBLIC_NONE = self.new PUBLIC => NONE
|
39
|
+
end
|
40
|
+
end
|
data/lib/parse/client.rb
CHANGED
@@ -28,8 +28,20 @@ module Parse
|
|
28
28
|
@http_client = http_client || Parse::HttpClient.new(API_SERVER)
|
29
29
|
end
|
30
30
|
|
31
|
+
def canonical_endpoint endpoint
|
32
|
+
case endpoint
|
33
|
+
when %r|/#{API_VERSION}/classes/_User|
|
34
|
+
endpoint.sub %r|/#{API_VERSION}/classes/_User|, "/#{API_VERSION}/users"
|
35
|
+
when %r|/#{API_VERSION}/classes/_Role|
|
36
|
+
endpoint.sub %r|/#{API_VERSION}/classes/_Role|, "/#{API_VERSION}/roles"
|
37
|
+
else
|
38
|
+
endpoint
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
31
42
|
def call_api method, endpoint, body=nil, opt_headers={}, &block
|
32
43
|
endpoint = "/#{API_VERSION}/#{endpoint}" unless endpoint[0] == '/'
|
44
|
+
endpoint = canonical_endpoint endpoint
|
33
45
|
headers = build_headers opt_headers
|
34
46
|
if body.is_a?(Hash)
|
35
47
|
body = Hash[*(body.to_a.map{|k, v| [k, URI.encode(v)]}.flatten)].to_json
|
data/lib/parse/object.rb
CHANGED
@@ -87,6 +87,8 @@ module Parse
|
|
87
87
|
if v.is_a? Hash
|
88
88
|
body_hash[k] =
|
89
89
|
case v['__type']
|
90
|
+
when nil
|
91
|
+
Parse::ACL.new v
|
90
92
|
when 'Date'
|
91
93
|
Date.parse v['iso']
|
92
94
|
when 'File'
|
@@ -145,6 +147,9 @@ module Parse
|
|
145
147
|
check_deleted!
|
146
148
|
hash = string_keyed_hash hash
|
147
149
|
@updated_hash.update hash
|
150
|
+
@updated_hash.reject! do |k, v|
|
151
|
+
v.is_a?(Parse::Relation) && !v.changed?
|
152
|
+
end
|
148
153
|
method = use_master_key ? :create! : :create
|
149
154
|
parse_client.send(method, self.parse_class_name, @updated_hash) do |response|
|
150
155
|
@parse_object_id = response['objectId']
|
data/lib/parse/pointer.rb
CHANGED
@@ -16,8 +16,16 @@ module Parse
|
|
16
16
|
@object ||= pointed_parse_class.find_by_id @raw_hash['objectId']
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
20
|
-
|
19
|
+
def to_h
|
20
|
+
{
|
21
|
+
"__type" => "Pointer",
|
22
|
+
"className" => "#{@raw_hash['className']}",
|
23
|
+
"objectId" => "#{@raw_hash['objectId']}"
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_json *args
|
28
|
+
to_h.to_json
|
21
29
|
end
|
22
30
|
|
23
31
|
private
|
data/lib/parse/relation.rb
CHANGED
@@ -5,6 +5,24 @@ module Parse
|
|
5
5
|
@parent_object = parent
|
6
6
|
@column_name = column_name
|
7
7
|
@raw_hash = hash
|
8
|
+
@added_pointers = []
|
9
|
+
@removed_pointers = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def add item
|
13
|
+
unless @removed_pointers.empty?
|
14
|
+
raise ArgumentError.new('Please save for removed items before adding')
|
15
|
+
end
|
16
|
+
item = item.pointer if item.is_a?(Parse::Object)
|
17
|
+
@added_pointers.push item
|
18
|
+
end
|
19
|
+
|
20
|
+
def remove item
|
21
|
+
unless @added_pointers.empty?
|
22
|
+
raise ArgumentError.new('Please save for added items before removing')
|
23
|
+
end
|
24
|
+
item = item.pointer if item.is_a?(Parse::Object)
|
25
|
+
@removed_pointers.push item
|
8
26
|
end
|
9
27
|
|
10
28
|
def load parse_client=Parse::Client.default
|
@@ -18,5 +36,33 @@ module Parse
|
|
18
36
|
end
|
19
37
|
@objects
|
20
38
|
end
|
39
|
+
|
40
|
+
def changed?
|
41
|
+
(@added_pointers.size + @removed_pointers.size) != 0
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_h
|
45
|
+
if not @added_pointers.empty?
|
46
|
+
{
|
47
|
+
"__op" => "AddRelation",
|
48
|
+
"objects" => @added_pointers.map(&:to_h)
|
49
|
+
}
|
50
|
+
elsif not @removed_pointers.empty?
|
51
|
+
{
|
52
|
+
"__op" => "RemoveRelation",
|
53
|
+
"objects" => @removed_pointers.map(&:to_h)
|
54
|
+
}
|
55
|
+
else
|
56
|
+
{
|
57
|
+
"__op" => "AddRelation",
|
58
|
+
"objects" => [nil]
|
59
|
+
}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_json *args
|
64
|
+
p to_h
|
65
|
+
to_h.to_json
|
66
|
+
end
|
21
67
|
end
|
22
68
|
end
|
data/lib/parse/role.rb
CHANGED
@@ -1,6 +1,50 @@
|
|
1
1
|
# coding:utf-8
|
2
2
|
module Parse
|
3
3
|
class Role < Object
|
4
|
-
|
4
|
+
class << self
|
5
|
+
def parse_class_name
|
6
|
+
'_Role'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize hash
|
11
|
+
super
|
12
|
+
|
13
|
+
#set_column 'roles', RoleItemArray.new(Parse::Role)
|
14
|
+
#set_column 'users', RoleItemArray.new(Parse::User)
|
15
|
+
set_column 'roles', Parse::Relation.new(self, 'roles', {'className' => '_Role'})
|
16
|
+
set_column 'users', Parse::Relation.new(self, 'users', {'className' => '_User'})
|
17
|
+
end
|
18
|
+
|
19
|
+
class RoleItemArray < Array
|
20
|
+
def initialize klass
|
21
|
+
@klass = klass
|
22
|
+
end
|
23
|
+
|
24
|
+
def add item
|
25
|
+
push \
|
26
|
+
case item
|
27
|
+
when String, Symbol
|
28
|
+
@klass.new('objectId' => item).pointer
|
29
|
+
when @klass
|
30
|
+
item.pointer
|
31
|
+
when Pointer
|
32
|
+
super
|
33
|
+
else
|
34
|
+
raise ArgumentError.new("wrong type: #{item.class.name}")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_h
|
39
|
+
{
|
40
|
+
"__op" => "AddRelation",
|
41
|
+
"objects" => map {|r| JSON.parse(r.to_json)}
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_json *args
|
46
|
+
to_h.to_json
|
47
|
+
end
|
48
|
+
end
|
5
49
|
end
|
6
50
|
end
|
data/lib/parse/user.rb
CHANGED
@@ -14,6 +14,10 @@ module Parse
|
|
14
14
|
def log_in username, password
|
15
15
|
self.new(username, password).log_in
|
16
16
|
end
|
17
|
+
|
18
|
+
def request_password_reset email
|
19
|
+
Parse::Client.default.call_api :post, 'requestPasswordReset', "email" => email
|
20
|
+
end
|
17
21
|
end
|
18
22
|
|
19
23
|
def initialize username=nil, password=nil, hash={}
|
data/lib/parse/version.rb
CHANGED
data/lib/parsecom.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parsecom
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-10-
|
12
|
+
date: 2013-10-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -72,6 +72,7 @@ files:
|
|
72
72
|
- LICENSE.txt
|
73
73
|
- README.md
|
74
74
|
- Rakefile
|
75
|
+
- lib/parse/acl.rb
|
75
76
|
- lib/parse/batch.rb
|
76
77
|
- lib/parse/batch_http_client.rb
|
77
78
|
- lib/parse/client.rb
|