parse-ruby-client 0.1.10 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -19,7 +19,9 @@ This currently depends on the gems 'json' and 'patron' for JSON support and HTTP
19
19
 
20
20
  ## Installation
21
21
 
22
- `gem "parse-ruby-client", "~> 0.1.10"`
22
+ [![Gem Version](https://badge.fury.io/rb/parse-ruby-client.png)](http://badge.fury.io/rb/parse-ruby-client)
23
+
24
+ `gem "parse-ruby-client"`
23
25
 
24
26
  ---
25
27
 
@@ -148,6 +150,24 @@ Parse::Query.new("GameScore") \
148
150
 
149
151
  ```
150
152
 
153
+ ### Relational Data
154
+
155
+ ```ruby
156
+ post = Parse::Object.new "Post"
157
+ post.save
158
+
159
+ comment = Parse::Object.new "Comment"
160
+ comment.save
161
+
162
+ post.array_add_relation("comments", comment.pointer)
163
+ post.save
164
+
165
+ q = Parse::Query.new("Comment")
166
+ q.related_to("comments", post.pointer)
167
+ comments = q.get
168
+ assert_equal comments.first["objectId"], comment["objectId"]
169
+ ```
170
+
151
171
  ## Push Notifications
152
172
 
153
173
  ```ruby
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.10
1
+ 0.1.11
data/features.md ADDED
@@ -0,0 +1,135 @@
1
+ ## Summary
2
+
3
+ parse-ruby-client lets you interact with Parse using Ruby. There are many uses. For example:
4
+
5
+ - A webserver can show data from Parse on a website.
6
+ - You can upload large amounts of data that will later be consumed in a mobile app.
7
+ - You can download recent data to run your own custom analytics.
8
+ - You can export all of your data if you no longer want to use Parse.
9
+
10
+ ### Quick Reference
11
+
12
+ #### Installation
13
+
14
+ `gem install parse-ruby-client` or add `gem "parse-ruby-client"` to your `Gemfile.`
15
+
16
+ #### Configuration
17
+
18
+ ```ruby
19
+ require 'parse-ruby-client'
20
+
21
+ Parse.init :application_id => "<your_app_id>",
22
+ :api_key => "<your_api_key>"
23
+ ```
24
+
25
+ ## Objects
26
+
27
+ The design philosophy behind parse-ruby-client is to stay out of the way as much as possible. Parse Objects, at the most basic level, act like Ruby `Hash` objects with Parse-specific methods tacked on.
28
+
29
+ ### Creating Objects
30
+
31
+ ```ruby
32
+ game_score = Parse::Object.new("GameScore")
33
+ game_score["score"] = 1337
34
+ game_score["playerName"] = "Sean Plott"
35
+ game_score["cheatMode"] = false
36
+ result = game_score.save
37
+ puts result
38
+ ```
39
+
40
+ This will return:
41
+
42
+ ```ruby
43
+ {"score"=>1337,
44
+ "playerName"=>"Sean Plott",
45
+ "cheatMode"=>false,
46
+ "createdAt"=>"2013-01-19T21:01:33.562Z",
47
+ "objectId"=>"GeqPWJdNqp"}
48
+ ```
49
+
50
+ ### Retrieving Objects
51
+
52
+ The easiest way to retrieve Objects is with `Parse::Query`:
53
+
54
+ ```ruby
55
+ game_score_query = Parse::Query.new("GameScore")
56
+ game_score_query.eq("objectId", "GeqPWJdNqp")
57
+ game_score = game_score_query.get
58
+ puts game_score
59
+ ```
60
+
61
+ This will return:
62
+
63
+ ```ruby
64
+ [{"score"=>1337,
65
+ "playerName"=>"Sean Plott",
66
+ "createdAt"=>"2013-01-19T21:01:33.562Z",
67
+ "updatedAt"=>"2013-01-19T21:01:33.562Z",
68
+ "objectId"=>"GeqPWJdNqp"}]
69
+ ```
70
+
71
+ Notice that this is an `Array` of results. For more information on queries, see TODO.
72
+
73
+ When retrieving objects that have pointers to children, you can fetch child objects by setting the `include` attribute. For instance, to fetch the object pointed to by the "game" key:
74
+
75
+ ```ruby
76
+ game_score_query = Parse::Query.new("GameScore")
77
+ game_score_query.eq("objectId", "GeqPWJdNqp")
78
+ game_score_query.include = "game"
79
+ game_score = game_score_query.get
80
+ ```
81
+
82
+ You can include multiple children pointers by separating key names by commas:
83
+
84
+ ```ruby
85
+ game_score_query.include = "game,genre"
86
+ ```
87
+
88
+ ### Updating Objects
89
+
90
+ To change the data on an object that already exists, just call `Parse::Object#save` on it. Any keys you don't specify will remain unchanged, so you can update just a subset of the object's data. For example, if we wanted to change the score field of our object:
91
+
92
+ ```ruby
93
+ game_score = Parse::Query.new("GameScore").eq("objectId", "GeqPWJdNqp").get.first
94
+ game_score["score"] = 73453
95
+ result = game_score.save
96
+ puts result
97
+ ```
98
+
99
+ This will return:
100
+
101
+ ```ruby
102
+ {"score"=>73453,
103
+ "playerName"=>"Sean Plott",
104
+ "createdAt"=>"2013-01-19T21:01:33.562Z",
105
+ "updatedAt"=>"2013-01-19T21:16:34.395Z",
106
+ "objectId"=>"GeqPWJdNqp"}
107
+ ```
108
+
109
+ #### Counters
110
+
111
+ To help with storing counter-type data, Parse provides the ability to atomically increment (or decrement) any number field. So, we can increment the score field like so:
112
+
113
+ ```ruby
114
+ game_score = Parse::Query.new("GameScore").eq("objectId", "GeqPWJdNqp").get.first
115
+ game_score["score"] = Parse::Increment.new(1)
116
+ game_score.save
117
+ ```
118
+
119
+ You can also use `Parse::Decrement.new(amount)`.
120
+
121
+ #### Arrays
122
+
123
+ ## Queries
124
+
125
+ ## Users
126
+
127
+ ## Roles
128
+
129
+ ## Files
130
+
131
+ ## Push Notifications
132
+
133
+ ## Installations
134
+
135
+ ## Geopoints
@@ -0,0 +1,321 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://api.parse.com/1/classes/Post
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{}'
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Accept:
13
+ - application/json
14
+ User-Agent:
15
+ - Parse for Ruby, 0.0
16
+ X-Parse-Master-Key:
17
+ - ''
18
+ X-Parse-Rest-Api-Key:
19
+ - PsXOTylMvpCsyhx7njRh06BzSsehrwywuYwD9UiN
20
+ X-Parse-Application-Id:
21
+ - X4gXxFjSqK9VHZZPFR32Cvp5wntIhDI5TESO18jB
22
+ X-Parse-Session-Token:
23
+ - ''
24
+ Expect:
25
+ - ''
26
+ response:
27
+ status:
28
+ code: 201
29
+ message: !binary |-
30
+ Q3JlYXRlZA==
31
+ headers:
32
+ !binary "QWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2lu":
33
+ - !binary |-
34
+ Kg==
35
+ !binary "QWNjZXNzLUNvbnRyb2wtUmVxdWVzdC1NZXRob2Q=":
36
+ - !binary |-
37
+ Kg==
38
+ !binary "Q2FjaGUtQ29udHJvbA==":
39
+ - !binary |-
40
+ bm8tY2FjaGU=
41
+ !binary "Q29udGVudC1UeXBl":
42
+ - !binary |-
43
+ YXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOA==
44
+ !binary "RGF0ZQ==":
45
+ - !binary |-
46
+ V2VkLCAxNiBKYW4gMjAxMyAxNDo0MDoxOCBHTVQ=
47
+ !binary "TG9jYXRpb24=":
48
+ - !binary |-
49
+ aHR0cHM6Ly9hcGkucGFyc2UuY29tLzEvY2xhc3Nlcy9Qb3N0L1M2T2lZbzdy
50
+ bkM=
51
+ !binary "U2VydmVy":
52
+ - !binary |-
53
+ bmdpbngvMS4yLjI=
54
+ !binary "U2V0LUNvb2tpZQ==":
55
+ - !binary |-
56
+ X3BhcnNlX3Nlc3Npb249QkFoN0Jra2lEM05sYzNOcGIyNWZhV1FHT2daRlJp
57
+ SWxOakk1WldVME1tVTVaV0l3TURGa1pESXdNek00T1dKaE16TTROMlExTm1Z
58
+ JTNELS01OGMwZmI1MjNhMmY0NTgwMmMyNmI2MDY0MzVmZjMyNjhjMTBkNDQ1
59
+ OyBkb21haW49LnBhcnNlLmNvbTsgcGF0aD0vOyBleHBpcmVzPU1vbiwgMTYt
60
+ SmFuLTIwMjMgMTQ6NDA6MTggR01UOyBzZWN1cmU7IEh0dHBPbmx5
61
+ !binary "U3RhdHVz":
62
+ - !binary |-
63
+ MjAxIENyZWF0ZWQ=
64
+ !binary "WC1SdW50aW1l":
65
+ - !binary |-
66
+ MC4xNzU4OTc=
67
+ !binary "WC1VYS1Db21wYXRpYmxl":
68
+ - !binary |-
69
+ SUU9RWRnZSxjaHJvbWU9MQ==
70
+ !binary "Q29udGVudC1MZW5ndGg=":
71
+ - !binary |-
72
+ NjQ=
73
+ !binary "Q29ubmVjdGlvbg==":
74
+ - !binary |-
75
+ a2VlcC1hbGl2ZQ==
76
+ body:
77
+ encoding: ASCII-8BIT
78
+ string: !binary |-
79
+ eyJjcmVhdGVkQXQiOiIyMDEzLTAxLTE2VDE0OjQwOjE4LjUyN1oiLCJvYmpl
80
+ Y3RJZCI6IlM2T2lZbzdybkMifQ==
81
+ http_version:
82
+ recorded_at: Wed, 16 Jan 2013 14:40:18 GMT
83
+ - request:
84
+ method: post
85
+ uri: https://api.parse.com/1/classes/Comment
86
+ body:
87
+ encoding: UTF-8
88
+ string: ! '{}'
89
+ headers:
90
+ Content-Type:
91
+ - application/json
92
+ Accept:
93
+ - application/json
94
+ User-Agent:
95
+ - Parse for Ruby, 0.0
96
+ X-Parse-Master-Key:
97
+ - ''
98
+ X-Parse-Rest-Api-Key:
99
+ - PsXOTylMvpCsyhx7njRh06BzSsehrwywuYwD9UiN
100
+ X-Parse-Application-Id:
101
+ - X4gXxFjSqK9VHZZPFR32Cvp5wntIhDI5TESO18jB
102
+ X-Parse-Session-Token:
103
+ - ''
104
+ Expect:
105
+ - ''
106
+ response:
107
+ status:
108
+ code: 201
109
+ message: !binary |-
110
+ Q3JlYXRlZA==
111
+ headers:
112
+ !binary "QWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2lu":
113
+ - !binary |-
114
+ Kg==
115
+ !binary "QWNjZXNzLUNvbnRyb2wtUmVxdWVzdC1NZXRob2Q=":
116
+ - !binary |-
117
+ Kg==
118
+ !binary "Q2FjaGUtQ29udHJvbA==":
119
+ - !binary |-
120
+ bm8tY2FjaGU=
121
+ !binary "Q29udGVudC1UeXBl":
122
+ - !binary |-
123
+ YXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOA==
124
+ !binary "RGF0ZQ==":
125
+ - !binary |-
126
+ V2VkLCAxNiBKYW4gMjAxMyAxNDo0MDoxOCBHTVQ=
127
+ !binary "TG9jYXRpb24=":
128
+ - !binary |-
129
+ aHR0cHM6Ly9hcGkucGFyc2UuY29tLzEvY2xhc3Nlcy9Db21tZW50L2FQRVRX
130
+ WWZvQmk=
131
+ !binary "U2VydmVy":
132
+ - !binary |-
133
+ bmdpbngvMS4yLjI=
134
+ !binary "U2V0LUNvb2tpZQ==":
135
+ - !binary |-
136
+ X3BhcnNlX3Nlc3Npb249QkFoN0Jra2lEM05sYzNOcGIyNWZhV1FHT2daRlJp
137
+ SWxaVGMxT1RObFpUVTRaVFZrWWpsak9EazVPV1JpWVRNMllqa3hNMkkzTlRZ
138
+ JTNELS05Zjg4MGNmNWU4MTZkM2NiZGQ2MmUwMDUzYjRhZTJmYjkzNmFhOGYx
139
+ OyBkb21haW49LnBhcnNlLmNvbTsgcGF0aD0vOyBleHBpcmVzPU1vbiwgMTYt
140
+ SmFuLTIwMjMgMTQ6NDA6MTggR01UOyBzZWN1cmU7IEh0dHBPbmx5
141
+ !binary "U3RhdHVz":
142
+ - !binary |-
143
+ MjAxIENyZWF0ZWQ=
144
+ !binary "WC1SdW50aW1l":
145
+ - !binary |-
146
+ MC4xNjYyNzE=
147
+ !binary "WC1VYS1Db21wYXRpYmxl":
148
+ - !binary |-
149
+ SUU9RWRnZSxjaHJvbWU9MQ==
150
+ !binary "Q29udGVudC1MZW5ndGg=":
151
+ - !binary |-
152
+ NjQ=
153
+ !binary "Q29ubmVjdGlvbg==":
154
+ - !binary |-
155
+ a2VlcC1hbGl2ZQ==
156
+ body:
157
+ encoding: ASCII-8BIT
158
+ string: !binary |-
159
+ eyJjcmVhdGVkQXQiOiIyMDEzLTAxLTE2VDE0OjQwOjE4LjczN1oiLCJvYmpl
160
+ Y3RJZCI6ImFQRVRXWWZvQmkifQ==
161
+ http_version:
162
+ recorded_at: Wed, 16 Jan 2013 14:40:18 GMT
163
+ - request:
164
+ method: put
165
+ uri: https://api.parse.com/1/classes/Post/S6OiYo7rnC
166
+ body:
167
+ encoding: UTF-8
168
+ string: ! '{"comments":{"__op":"AddRelation","objects":[{"__type":"Pointer","className":"Comment","objectId":"aPETWYfoBi"}]}}'
169
+ headers:
170
+ Content-Type:
171
+ - application/json
172
+ Accept:
173
+ - application/json
174
+ User-Agent:
175
+ - Parse for Ruby, 0.0
176
+ X-Parse-Master-Key:
177
+ - ''
178
+ X-Parse-Rest-Api-Key:
179
+ - PsXOTylMvpCsyhx7njRh06BzSsehrwywuYwD9UiN
180
+ X-Parse-Application-Id:
181
+ - X4gXxFjSqK9VHZZPFR32Cvp5wntIhDI5TESO18jB
182
+ X-Parse-Session-Token:
183
+ - ''
184
+ Expect:
185
+ - ''
186
+ response:
187
+ status:
188
+ code: 200
189
+ message: !binary |-
190
+ T0s=
191
+ headers:
192
+ !binary "QWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2lu":
193
+ - !binary |-
194
+ Kg==
195
+ !binary "QWNjZXNzLUNvbnRyb2wtUmVxdWVzdC1NZXRob2Q=":
196
+ - !binary |-
197
+ Kg==
198
+ !binary "Q2FjaGUtQ29udHJvbA==":
199
+ - !binary |-
200
+ bWF4LWFnZT0wLCBwcml2YXRlLCBtdXN0LXJldmFsaWRhdGU=
201
+ !binary "Q29udGVudC1UeXBl":
202
+ - !binary |-
203
+ YXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOA==
204
+ !binary "RGF0ZQ==":
205
+ - !binary |-
206
+ V2VkLCAxNiBKYW4gMjAxMyAxNDo0MDoxOSBHTVQ=
207
+ !binary "RXRhZw==":
208
+ - !binary |-
209
+ ImRkYWZhMDJhMjM4MjNkZWI4ZTM0YTI0ODk2NjllODM2Ig==
210
+ !binary "U2VydmVy":
211
+ - !binary |-
212
+ bmdpbngvMS4yLjI=
213
+ !binary "U2V0LUNvb2tpZQ==":
214
+ - !binary |-
215
+ X3BhcnNlX3Nlc3Npb249QkFoN0Jra2lEM05sYzNOcGIyNWZhV1FHT2daRlJp
216
+ SWxORGN6T1dWaU1qUXlNVFptT1dZME9EbG1NRE0wTldFeVpUZzJNbVptTlRB
217
+ JTNELS0wN2MyOWZiYjQwYTY0MzllNGQ2ZTk3ZmNiODg1OGYxYzYyNTJlNzJi
218
+ OyBkb21haW49LnBhcnNlLmNvbTsgcGF0aD0vOyBleHBpcmVzPU1vbiwgMTYt
219
+ SmFuLTIwMjMgMTQ6NDA6MTkgR01UOyBzZWN1cmU7IEh0dHBPbmx5
220
+ !binary "U3RhdHVz":
221
+ - !binary |-
222
+ MjAwIE9L
223
+ !binary "WC1SdW50aW1l":
224
+ - !binary |-
225
+ MC4zMzQxMjU=
226
+ !binary "WC1VYS1Db21wYXRpYmxl":
227
+ - !binary |-
228
+ SUU9RWRnZSxjaHJvbWU9MQ==
229
+ !binary "Q29udGVudC1MZW5ndGg=":
230
+ - !binary |-
231
+ NDA=
232
+ !binary "Q29ubmVjdGlvbg==":
233
+ - !binary |-
234
+ a2VlcC1hbGl2ZQ==
235
+ body:
236
+ encoding: ASCII-8BIT
237
+ string: !binary |-
238
+ eyJ1cGRhdGVkQXQiOiIyMDEzLTAxLTE2VDE0OjQwOjE4Ljk3N1oifQ==
239
+ http_version:
240
+ recorded_at: Wed, 16 Jan 2013 14:40:19 GMT
241
+ - request:
242
+ method: get
243
+ uri: https://api.parse.com/1/classes/Comment?where=%7B%22$relatedTo%22:%7B%22object%22:%7B%22__type%22:%22Pointer%22,%22className%22:%22Post%22,%22objectId%22:%22S6OiYo7rnC%22%7D,%22key%22:%22comments%22%7D%7D
244
+ body:
245
+ encoding: US-ASCII
246
+ string: ''
247
+ headers:
248
+ Content-Type:
249
+ - application/json
250
+ Accept:
251
+ - application/json
252
+ User-Agent:
253
+ - Parse for Ruby, 0.0
254
+ X-Parse-Master-Key:
255
+ - ''
256
+ X-Parse-Rest-Api-Key:
257
+ - PsXOTylMvpCsyhx7njRh06BzSsehrwywuYwD9UiN
258
+ X-Parse-Application-Id:
259
+ - X4gXxFjSqK9VHZZPFR32Cvp5wntIhDI5TESO18jB
260
+ X-Parse-Session-Token:
261
+ - ''
262
+ Expect:
263
+ - ''
264
+ response:
265
+ status:
266
+ code: 200
267
+ message: !binary |-
268
+ T0s=
269
+ headers:
270
+ !binary "QWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2lu":
271
+ - !binary |-
272
+ Kg==
273
+ !binary "QWNjZXNzLUNvbnRyb2wtUmVxdWVzdC1NZXRob2Q=":
274
+ - !binary |-
275
+ Kg==
276
+ !binary "Q2FjaGUtQ29udHJvbA==":
277
+ - !binary |-
278
+ bWF4LWFnZT0wLCBwcml2YXRlLCBtdXN0LXJldmFsaWRhdGU=
279
+ !binary "Q29udGVudC1UeXBl":
280
+ - !binary |-
281
+ YXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOA==
282
+ !binary "RGF0ZQ==":
283
+ - !binary |-
284
+ V2VkLCAxNiBKYW4gMjAxMyAxNDo0MDoyMCBHTVQ=
285
+ !binary "RXRhZw==":
286
+ - !binary |-
287
+ IjY5OTYyM2M3NTY5ZDk0MzA4OTVjMDE1NmRhNjhlOWFlIg==
288
+ !binary "U2VydmVy":
289
+ - !binary |-
290
+ bmdpbngvMS4yLjI=
291
+ !binary "U2V0LUNvb2tpZQ==":
292
+ - !binary |-
293
+ X3BhcnNlX3Nlc3Npb249QkFoN0Jra2lEM05sYzNOcGIyNWZhV1FHT2daRlJp
294
+ SWxObVEyT1ROalpUQTBPV0U0WWpVNE5Ea3hOakUzTURJeU9EWTFOVFptTW1F
295
+ JTNELS0xYmM5MzE0Nzk0OTE5NmZmOGI2YmNkZjliNTM4ZWIyNzk1YTY3NjEy
296
+ OyBkb21haW49LnBhcnNlLmNvbTsgcGF0aD0vOyBleHBpcmVzPU1vbiwgMTYt
297
+ SmFuLTIwMjMgMTQ6NDA6MjAgR01UOyBzZWN1cmU7IEh0dHBPbmx5
298
+ !binary "U3RhdHVz":
299
+ - !binary |-
300
+ MjAwIE9L
301
+ !binary "WC1SdW50aW1l":
302
+ - !binary |-
303
+ MC42ODY4Mzg=
304
+ !binary "WC1VYS1Db21wYXRpYmxl":
305
+ - !binary |-
306
+ SUU9RWRnZSxjaHJvbWU9MQ==
307
+ !binary "Q29udGVudC1MZW5ndGg=":
308
+ - !binary |-
309
+ MTE3
310
+ !binary "Q29ubmVjdGlvbg==":
311
+ - !binary |-
312
+ a2VlcC1hbGl2ZQ==
313
+ body:
314
+ encoding: ASCII-8BIT
315
+ string: !binary |-
316
+ eyJyZXN1bHRzIjpbeyJjcmVhdGVkQXQiOiIyMDEzLTAxLTE2VDE0OjQwOjE4
317
+ LjczN1oiLCJ1cGRhdGVkQXQiOiIyMDEzLTAxLTE2VDE0OjQwOjE4LjczN1oi
318
+ LCJvYmplY3RJZCI6ImFQRVRXWWZvQmkifV19
319
+ http_version:
320
+ recorded_at: Wed, 16 Jan 2013 14:40:20 GMT
321
+ recorded_with: VCR 2.0.1
@@ -0,0 +1,180 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://api.parse.com/1/classes/Post
6
+ body:
7
+ encoding: UTF-8
8
+ string: "{\"title\":\"foo\"}"
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Accept:
13
+ - application/json
14
+ User-Agent:
15
+ - Parse for Ruby, 0.0
16
+ X-Parse-Master-Key:
17
+ - ""
18
+ X-Parse-Rest-Api-Key:
19
+ - jYdptjS76YHikuIFfJEgHD8UMIjH6cp2rWz4fo2C
20
+ X-Parse-Application-Id:
21
+ - hnJRtntbYPvWfjqcqLZsdFaOKT0F3SfNU7Kc7woN
22
+ X-Parse-Session-Token:
23
+ - ""
24
+ Expect:
25
+ - ""
26
+ response:
27
+ status:
28
+ code: 201
29
+ message: Created
30
+ headers:
31
+ Access-Control-Allow-Origin:
32
+ - "*"
33
+ Access-Control-Request-Method:
34
+ - "*"
35
+ Cache-Control:
36
+ - no-cache
37
+ Content-Type:
38
+ - application/json; charset=utf-8
39
+ Date:
40
+ - Thu, 17 Jan 2013 17:13:34 GMT
41
+ Location:
42
+ - https://api.parse.com/1/classes/Post/0ylGAv4qfA
43
+ Server:
44
+ - nginx/1.2.2
45
+ Set-Cookie:
46
+ - _parse_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlYzliMjZiMzllZGFjMDA3Yzk5ZjE3ZjUwMDBlZGEwN2M%3D--f4d278f69aa2353017fa480914551a210a78d2c7; domain=.parse.com; path=/; expires=Tue, 17-Jan-2023 17:13:34 GMT; secure; HttpOnly
47
+ Status:
48
+ - 201 Created
49
+ X-Runtime:
50
+ - "0.072524"
51
+ X-Ua-Compatible:
52
+ - IE=Edge,chrome=1
53
+ Content-Length:
54
+ - "64"
55
+ Connection:
56
+ - keep-alive
57
+ body:
58
+ encoding: ASCII-8BIT
59
+ string: "{\"createdAt\":\"2013-01-17T17:13:34.358Z\",\"objectId\":\"0ylGAv4qfA\"}"
60
+ http_version:
61
+ recorded_at: Thu, 17 Jan 2013 17:13:34 GMT
62
+ - request:
63
+ method: post
64
+ uri: https://api.parse.com/1/classes/Post
65
+ body:
66
+ encoding: UTF-8
67
+ string: "{\"title\":\"bar\",\"other\":{\"__type\":\"Pointer\",\"className\":\"Post\",\"objectId\":\"0ylGAv4qfA\"}}"
68
+ headers:
69
+ Content-Type:
70
+ - application/json
71
+ Accept:
72
+ - application/json
73
+ User-Agent:
74
+ - Parse for Ruby, 0.0
75
+ X-Parse-Master-Key:
76
+ - ""
77
+ X-Parse-Rest-Api-Key:
78
+ - jYdptjS76YHikuIFfJEgHD8UMIjH6cp2rWz4fo2C
79
+ X-Parse-Application-Id:
80
+ - hnJRtntbYPvWfjqcqLZsdFaOKT0F3SfNU7Kc7woN
81
+ X-Parse-Session-Token:
82
+ - ""
83
+ Expect:
84
+ - ""
85
+ response:
86
+ status:
87
+ code: 201
88
+ message: Created
89
+ headers:
90
+ Access-Control-Allow-Origin:
91
+ - "*"
92
+ Access-Control-Request-Method:
93
+ - "*"
94
+ Cache-Control:
95
+ - no-cache
96
+ Content-Type:
97
+ - application/json; charset=utf-8
98
+ Date:
99
+ - Thu, 17 Jan 2013 17:13:34 GMT
100
+ Location:
101
+ - https://api.parse.com/1/classes/Post/i0HlajhFXX
102
+ Server:
103
+ - nginx/1.2.2
104
+ Set-Cookie:
105
+ - _parse_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlMDExMzk3ZTdlOTEzNDEyYjMyZGZkZDE5MWY4MDY4YWE%3D--ec2534ca428c5a0c73ac3cf5634bcb7881447eef; domain=.parse.com; path=/; expires=Tue, 17-Jan-2023 17:13:34 GMT; secure; HttpOnly
106
+ Status:
107
+ - 201 Created
108
+ X-Runtime:
109
+ - "0.254273"
110
+ X-Ua-Compatible:
111
+ - IE=Edge,chrome=1
112
+ Content-Length:
113
+ - "64"
114
+ Connection:
115
+ - keep-alive
116
+ body:
117
+ encoding: ASCII-8BIT
118
+ string: "{\"createdAt\":\"2013-01-17T17:13:34.465Z\",\"objectId\":\"i0HlajhFXX\"}"
119
+ http_version:
120
+ recorded_at: Thu, 17 Jan 2013 17:13:34 GMT
121
+ - request:
122
+ method: get
123
+ uri: https://api.parse.com/1/classes/Post?include=other&where=%7B%22objectId%22:%22i0HlajhFXX%22%7D
124
+ body:
125
+ encoding: US-ASCII
126
+ string: ""
127
+ headers:
128
+ Content-Type:
129
+ - application/json
130
+ Accept:
131
+ - application/json
132
+ User-Agent:
133
+ - Parse for Ruby, 0.0
134
+ X-Parse-Master-Key:
135
+ - ""
136
+ X-Parse-Rest-Api-Key:
137
+ - jYdptjS76YHikuIFfJEgHD8UMIjH6cp2rWz4fo2C
138
+ X-Parse-Application-Id:
139
+ - hnJRtntbYPvWfjqcqLZsdFaOKT0F3SfNU7Kc7woN
140
+ X-Parse-Session-Token:
141
+ - ""
142
+ Expect:
143
+ - ""
144
+ response:
145
+ status:
146
+ code: 200
147
+ message: OK
148
+ headers:
149
+ Access-Control-Allow-Origin:
150
+ - "*"
151
+ Access-Control-Request-Method:
152
+ - "*"
153
+ Cache-Control:
154
+ - max-age=0, private, must-revalidate
155
+ Content-Type:
156
+ - application/json; charset=utf-8
157
+ Date:
158
+ - Thu, 17 Jan 2013 17:13:35 GMT
159
+ Etag:
160
+ - "\"0c16d470804a385fb35d9e40b4928e34\""
161
+ Server:
162
+ - nginx/1.2.2
163
+ Set-Cookie:
164
+ - _parse_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlNDQ1NzVkYTExZTBjOTVlOWExOTQwNmNmZDFiZTE3NGU%3D--781e16e0634f86cdd9a44ba4baa2c12fe9a8d531; domain=.parse.com; path=/; expires=Tue, 17-Jan-2023 17:13:35 GMT; secure; HttpOnly
165
+ Status:
166
+ - 200 OK
167
+ X-Runtime:
168
+ - "0.269586"
169
+ X-Ua-Compatible:
170
+ - IE=Edge,chrome=1
171
+ Content-Length:
172
+ - "294"
173
+ Connection:
174
+ - keep-alive
175
+ body:
176
+ encoding: ASCII-8BIT
177
+ string: "{\"results\":[{\"title\":\"bar\",\"other\":{\"title\":\"foo\",\"createdAt\":\"2013-01-17T17:13:34.358Z\",\"updatedAt\":\"2013-01-17T17:13:34.358Z\",\"objectId\":\"0ylGAv4qfA\",\"__type\":\"Object\",\"className\":\"Post\"},\"createdAt\":\"2013-01-17T17:13:34.465Z\",\"updatedAt\":\"2013-01-17T17:13:34.465Z\",\"objectId\":\"i0HlajhFXX\"}]}"
178
+ http_version:
179
+ recorded_at: Thu, 17 Jan 2013 17:13:35 GMT
180
+ recorded_with: VCR 2.0.1
@@ -48,6 +48,10 @@ module Parse
48
48
  def get
49
49
  Parse.get @class_name, @parse_object_id if @parse_object_id
50
50
  end
51
+
52
+ def to_s
53
+ "#{@class_name}:#{@parse_object_id}"
54
+ end
51
55
  end
52
56
 
53
57
  # Date
@@ -294,6 +298,10 @@ module Parse
294
298
  def to_json(*a)
295
299
  as_json.to_json(*a)
296
300
  end
301
+
302
+ def to_s
303
+ "(#{latitude}, #{longitude})"
304
+ end
297
305
  end
298
306
 
299
307
  # File
@@ -334,4 +342,4 @@ module Parse
334
342
  end
335
343
 
336
344
 
337
- end
345
+ end
data/lib/parse/error.rb CHANGED
@@ -16,8 +16,10 @@ module Parse
16
16
 
17
17
  def initialize(response)
18
18
  @response = response
19
- @code = response["code"]
20
- @error = response["error"]
19
+ if response
20
+ @code = response["code"]
21
+ @error = response["error"]
22
+ end
21
23
 
22
24
  super("#{@code}: #{@error}")
23
25
  end
data/lib/parse/object.rb CHANGED
@@ -133,6 +133,14 @@ module Parse
133
133
  as_json.to_json(*a)
134
134
  end
135
135
 
136
+ def to_s
137
+ "#{@class_name}:#{@parse_object_id} #{super}"
138
+ end
139
+
140
+ def inspect
141
+ "#{@class_name}:#{@parse_object_id} #{super}"
142
+ end
143
+
136
144
  # Update the fields of the local Parse object with the current
137
145
  # values from the API.
138
146
  def refresh
@@ -161,6 +169,10 @@ module Parse
161
169
  array_op(field, Protocol::KEY_ADD, value)
162
170
  end
163
171
 
172
+ def array_add_relation(field, value)
173
+ array_op(field, Protocol::KEY_ADD_RELATION, value)
174
+ end
175
+
164
176
  def array_add_unique(field, value)
165
177
  array_op(field, Protocol::KEY_ADD_UNIQUE, value)
166
178
  end
@@ -217,6 +229,9 @@ module Parse
217
229
  when Protocol::KEY_ADD
218
230
  self[field] ||= []
219
231
  self[field] << value
232
+ when Protocol::KEY_ADD_RELATION
233
+ self[field] ||= []
234
+ self[field] << value
220
235
  when Protocol::KEY_ADD_UNIQUE
221
236
  self[field] ||= []
222
237
  self[field] << value unless self[field].include?(value)
@@ -225,4 +240,4 @@ module Parse
225
240
  end
226
241
  end
227
242
  end
228
- end
243
+ end
@@ -65,6 +65,7 @@ module Parse
65
65
  # array ops
66
66
  KEY_OBJECTS = "objects"
67
67
  KEY_ADD = "Add"
68
+ KEY_ADD_RELATION= "AddRelation"
68
69
  KEY_ADD_UNIQUE = "AddUnique"
69
70
  KEY_REMOVE = "Remove"
70
71
 
@@ -73,8 +74,6 @@ module Parse
73
74
  # The JSON key used to identify the datatype of a special value.
74
75
  KEY_TYPE = "__type"
75
76
 
76
- TYPE_OBJECT = "Object"
77
-
78
77
  # The JSON key used to specify the numerical value in the
79
78
  # increment/decrement API call.
80
79
  KEY_AMOUNT = "amount"
@@ -90,6 +89,8 @@ module Parse
90
89
  # Operation name for decrementing an objects field value remotely
91
90
  OP_DECREMENT = "Decrement"
92
91
 
92
+ # The data type name for special JSON objects representing a full object
93
+ TYPE_OBJECT = "Object"
93
94
 
94
95
  # The data type name for special JSON objects representing a reference
95
96
  # to another Parse object.
@@ -170,4 +171,4 @@ module Parse
170
171
  "/#{VERSION}/#{BATCH_REQUEST_URI}"
171
172
  end
172
173
  end
173
- end
174
+ end
data/lib/parse/query.rb CHANGED
@@ -86,6 +86,11 @@ module Parse
86
86
  self
87
87
  end
88
88
 
89
+ def related_to(field,value)
90
+ h = {"object" => value, "key" => field}
91
+ add_constraint("$relatedTo", h )
92
+ end
93
+
89
94
  def exists(field, value = true)
90
95
  add_constraint field, { "$exists" => value }
91
96
  self
@@ -131,11 +136,11 @@ module Parse
131
136
  query.merge!(:order => order_string)
132
137
  end
133
138
 
134
- def merge_attribute(attribute, query)
139
+ def merge_attribute(attribute, query, query_field = nil)
135
140
  value = self.instance_variable_get("@#{attribute.to_s}")
136
141
  return if value.nil?
137
- query.merge!(attribute => value)
142
+ query.merge!((query_field || attribute) => value)
138
143
  end
139
144
  end
140
145
 
141
- end
146
+ end
data/lib/parse/util.rb CHANGED
@@ -7,7 +7,6 @@ module Parse
7
7
  # @param class_name [Object]
8
8
  # @param obj [Object]
9
9
  def Parse.parse_json(class_name, obj)
10
-
11
10
  if obj.nil?
12
11
  nil
13
12
 
@@ -48,7 +47,7 @@ module Parse
48
47
  when Protocol::TYPE_FILE
49
48
  Parse::File.new obj
50
49
  when Protocol::TYPE_OBJECT # used for relation queries, e.g. "?include=post"
51
- Parse::Object.new(obj[Parse::Protocol::KEY_CLASS_NAME], obj)
50
+ Parse::Object.new obj[Protocol::KEY_CLASS_NAME], Hash[obj.map{|k,v| [k, parse_json(nil, v)]}]
52
51
  end
53
52
  end
54
53
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "parse-ruby-client"
8
- s.version = "0.1.10"
8
+ s.version = "0.1.11"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Alan deLevie", "Adam Alpern"]
12
- s.date = "2013-01-12"
12
+ s.date = "2013-01-24"
13
13
  s.description = "A simple Ruby client for the parse.com REST API"
14
14
  s.email = "adelevie@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -25,7 +25,9 @@ Gem::Specification.new do |s|
25
25
  "Rakefile",
26
26
  "VERSION",
27
27
  "example.rb",
28
+ "features.md",
28
29
  "fixtures/vcr_cassettes/test_array_add.yml",
30
+ "fixtures/vcr_cassettes/test_array_add_relation.yml",
29
31
  "fixtures/vcr_cassettes/test_batch_create_object.yml",
30
32
  "fixtures/vcr_cassettes/test_batch_delete_object.yml",
31
33
  "fixtures/vcr_cassettes/test_batch_run.yml",
@@ -35,6 +37,7 @@ Gem::Specification.new do |s|
35
37
  "fixtures/vcr_cassettes/test_deep_parse.yml",
36
38
  "fixtures/vcr_cassettes/test_destroy.yml",
37
39
  "fixtures/vcr_cassettes/test_get.yml",
40
+ "fixtures/vcr_cassettes/test_include.yml",
38
41
  "fixtures/vcr_cassettes/test_new_model.yml",
39
42
  "fixtures/vcr_cassettes/test_new_object.yml",
40
43
  "fixtures/vcr_cassettes/test_nils_delete_keys.yml",
data/test/test_object.rb CHANGED
@@ -122,4 +122,22 @@ class TestObject < Test::Unit::TestCase
122
122
  assert_equal ["hello", "goodbye"], post["chapters"]
123
123
  end
124
124
  end
125
+
126
+ def test_array_add_relation
127
+ VCR.use_cassette('test_array_add_relation', :record => :new_episodes) do
128
+ post = Parse::Object.new "Post"
129
+ post.save
130
+
131
+ comment = Parse::Object.new "Comment"
132
+ comment.save
133
+
134
+ post.array_add_relation("comments", comment.pointer)
135
+ post.save
136
+
137
+ q = Parse::Query.new("Comment")
138
+ q.related_to("comments", post.pointer)
139
+ comments = q.get
140
+ assert_equal comments.first["objectId"], comment["objectId"]
141
+ end
142
+ end
125
143
  end
data/test/test_query.rb CHANGED
@@ -30,6 +30,16 @@ class TestQuery < Test::Unit::TestCase
30
30
  assert_equal q.where["player"], { "$regex" => "regex voodoo"}
31
31
  end
32
32
 
33
+ def test_related_to
34
+ q = Parse::Query.new "Comment"
35
+ pointer = Parse::Pointer.new(class_name: "Post", parse_object_id: '1234')
36
+ q.related_to("comments", pointer)
37
+
38
+ assert_not_nil q.where["$relatedTo"]
39
+ assert_equal pointer, q.where["$relatedTo"]["object"]
40
+ assert_equal q.where["$relatedTo"]["key"], "comments"
41
+ end
42
+
33
43
  def test_eq
34
44
  q = Parse::Query.new "TestQuery"
35
45
  q.eq("points", 5)
@@ -59,6 +69,25 @@ class TestQuery < Test::Unit::TestCase
59
69
  end
60
70
  end
61
71
 
72
+ def test_include
73
+ VCR.use_cassette('test_include', :record => :new_episodes) do
74
+ post_1 = Parse::Object.new "Post"
75
+ post_1['title'] = 'foo'
76
+ post_1.save
77
+
78
+ post_2 = Parse::Object.new "Post"
79
+ post_2['title'] = 'bar'
80
+ post_2['other'] = post_1.pointer
81
+ post_2.save
82
+
83
+ q = Parse::Query.new "Post"
84
+ q.eq('objectId', post_2.parse_object_id)
85
+ q.include = 'other'
86
+
87
+ assert_equal 'foo', q.get.first['other']['title']
88
+ end
89
+ end
90
+
62
91
  def test_or
63
92
  #VCR.use_cassette('test_or', :record => :new_episodes) do
64
93
  foo = Parse::Object.new "Post"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parse-ruby-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.10
4
+ version: 0.1.11
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-01-12 00:00:00.000000000 Z
13
+ date: 2013-01-24 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: patron
@@ -172,7 +172,9 @@ files:
172
172
  - Rakefile
173
173
  - VERSION
174
174
  - example.rb
175
+ - features.md
175
176
  - fixtures/vcr_cassettes/test_array_add.yml
177
+ - fixtures/vcr_cassettes/test_array_add_relation.yml
176
178
  - fixtures/vcr_cassettes/test_batch_create_object.yml
177
179
  - fixtures/vcr_cassettes/test_batch_delete_object.yml
178
180
  - fixtures/vcr_cassettes/test_batch_run.yml
@@ -182,6 +184,7 @@ files:
182
184
  - fixtures/vcr_cassettes/test_deep_parse.yml
183
185
  - fixtures/vcr_cassettes/test_destroy.yml
184
186
  - fixtures/vcr_cassettes/test_get.yml
187
+ - fixtures/vcr_cassettes/test_include.yml
185
188
  - fixtures/vcr_cassettes/test_new_model.yml
186
189
  - fixtures/vcr_cassettes/test_new_object.yml
187
190
  - fixtures/vcr_cassettes/test_nils_delete_keys.yml
@@ -237,7 +240,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
237
240
  version: '0'
238
241
  segments:
239
242
  - 0
240
- hash: 1980852008607816263
243
+ hash: 4089803935142513409
241
244
  required_rubygems_version: !ruby/object:Gem::Requirement
242
245
  none: false
243
246
  requirements: