parse_resource 1.7.2 → 1.7.3

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.
Files changed (41) hide show
  1. data/.travis.yml +6 -0
  2. data/Gemfile +5 -1
  3. data/Gemfile.lock +11 -1
  4. data/README.md +21 -8
  5. data/VERSION +1 -1
  6. data/fixtures/vcr_cassettes/test_all.yml +161 -0
  7. data/fixtures/vcr_cassettes/test_attribute_getters.yml +57 -0
  8. data/fixtures/vcr_cassettes/test_attribute_setters.yml +57 -0
  9. data/fixtures/vcr_cassettes/test_authenticate.yml +155 -0
  10. data/fixtures/vcr_cassettes/test_chained_wheres.yml +161 -0
  11. data/fixtures/vcr_cassettes/test_count.yml +411 -0
  12. data/fixtures/vcr_cassettes/test_create.yml +57 -0
  13. data/fixtures/vcr_cassettes/test_created_at.yml +57 -0
  14. data/fixtures/vcr_cassettes/test_destroy.yml +157 -0
  15. data/fixtures/vcr_cassettes/test_destroy_all.yml +207 -0
  16. data/fixtures/vcr_cassettes/test_each.yml +269 -0
  17. data/fixtures/vcr_cassettes/test_find.yml +107 -0
  18. data/fixtures/vcr_cassettes/test_find_all_by.yml +157 -0
  19. data/fixtures/vcr_cassettes/test_find_by.yml +157 -0
  20. data/fixtures/vcr_cassettes/test_first.yml +107 -0
  21. data/fixtures/vcr_cassettes/test_id.yml +57 -0
  22. data/fixtures/vcr_cassettes/test_limit.yml +864 -0
  23. data/fixtures/vcr_cassettes/test_map.yml +269 -0
  24. data/fixtures/vcr_cassettes/test_save.yml +111 -0
  25. data/fixtures/vcr_cassettes/test_skip.yml +843 -0
  26. data/fixtures/vcr_cassettes/test_update.yml +111 -0
  27. data/fixtures/vcr_cassettes/test_updated_at.yml +111 -0
  28. data/fixtures/vcr_cassettes/test_username_should_be_unique.yml +109 -0
  29. data/fixtures/vcr_cassettes/test_where.yml +107 -0
  30. data/lib/parse_resource/base.rb +66 -69
  31. data/lib/parse_resource/parse_user.rb +1 -1
  32. data/lib/parse_resource/query.rb +9 -9
  33. data/parse_resource.gemspec +41 -7
  34. data/parse_resource.yml +12 -0
  35. data/test/active_model_lint_test.rb +5 -6
  36. data/test/helper.rb +8 -0
  37. data/test/test_parse_resource.rb +183 -117
  38. data/test/test_parse_user.rb +39 -32
  39. data/test/test_query_options.rb +43 -17
  40. metadata +149 -26
  41. data/test/test_associations.rb +0 -105
@@ -0,0 +1,111 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://FKEzdzDgEyghLDFgIVHYJehVlWpfVtUmEv4MUEkJ:bOYO7usWbrcIbL5L5bPzlYrSonQRvwJecC1XLsuN@api.parse.com/1/classes/Post
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{"title":"stale title"}'
9
+ headers:
10
+ Accept:
11
+ - ! '*/*; q=0.5, application/xml'
12
+ Accept-Encoding:
13
+ - gzip, deflate
14
+ Content-Type:
15
+ - application/json
16
+ Content-Length:
17
+ - '23'
18
+ User-Agent:
19
+ - Ruby
20
+ response:
21
+ status:
22
+ code: 201
23
+ message: Created
24
+ headers:
25
+ Access-Control-Allow-Origin:
26
+ - https://parse.com, https://www.parse.com
27
+ Access-Control-Request-Method:
28
+ - ! '*'
29
+ Cache-Control:
30
+ - no-cache
31
+ Content-Type:
32
+ - application/json; charset=utf-8
33
+ Date:
34
+ - Thu, 20 Sep 2012 04:31:52 GMT
35
+ Location:
36
+ - https://api.parse.com/1/classes/Post/FcekFSi2PF
37
+ Server:
38
+ - nginx/1.2.2
39
+ Set-Cookie:
40
+ - _parse_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlMjgyMTU1ZDQ4MTUzNTU5ZWNlMzI1NDdiODIyY2NlZjQ%3D--270ea83cbc64cd6c5db92b481ad13a42bf0cd608;
41
+ domain=.parse.com; path=/; expires=Tue, 20-Sep-2022 04:31:52 GMT; HttpOnly
42
+ Status:
43
+ - 201 Created
44
+ X-Runtime:
45
+ - '0.021668'
46
+ X-Ua-Compatible:
47
+ - IE=Edge,chrome=1
48
+ Content-Length:
49
+ - '64'
50
+ Connection:
51
+ - keep-alive
52
+ body:
53
+ encoding: US-ASCII
54
+ string: ! '{"createdAt":"2012-09-20T04:31:52.369Z","objectId":"FcekFSi2PF"}'
55
+ http_version:
56
+ recorded_at: Thu, 20 Sep 2012 04:31:52 GMT
57
+ - request:
58
+ method: put
59
+ uri: https://FKEzdzDgEyghLDFgIVHYJehVlWpfVtUmEv4MUEkJ:bOYO7usWbrcIbL5L5bPzlYrSonQRvwJecC1XLsuN@api.parse.com/1/classes/Post/FcekFSi2PF
60
+ body:
61
+ encoding: UTF-8
62
+ string: ! '{"title":"updated title"}'
63
+ headers:
64
+ Accept:
65
+ - ! '*/*; q=0.5, application/xml'
66
+ Accept-Encoding:
67
+ - gzip, deflate
68
+ Content-Type:
69
+ - application/json
70
+ Content-Length:
71
+ - '25'
72
+ User-Agent:
73
+ - Ruby
74
+ response:
75
+ status:
76
+ code: 200
77
+ message: OK
78
+ headers:
79
+ Access-Control-Allow-Origin:
80
+ - https://parse.com, https://www.parse.com
81
+ Access-Control-Request-Method:
82
+ - ! '*'
83
+ Cache-Control:
84
+ - max-age=0, private, must-revalidate
85
+ Content-Type:
86
+ - application/json; charset=utf-8
87
+ Date:
88
+ - Thu, 20 Sep 2012 04:31:52 GMT
89
+ Etag:
90
+ - ! '"f0cb040baef5598b360d65bc4395e3ed"'
91
+ Server:
92
+ - nginx/1.2.2
93
+ Set-Cookie:
94
+ - _parse_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlNzVkZjRkNjNlZWZkNDZlMmZjZjhjZGVlMWFkMTA0NmQ%3D--d460531b714805ef65a54d0ce78f6afcb6a66205;
95
+ domain=.parse.com; path=/; expires=Tue, 20-Sep-2022 04:31:52 GMT; HttpOnly
96
+ Status:
97
+ - 200 OK
98
+ X-Runtime:
99
+ - '0.020681'
100
+ X-Ua-Compatible:
101
+ - IE=Edge,chrome=1
102
+ Content-Length:
103
+ - '40'
104
+ Connection:
105
+ - keep-alive
106
+ body:
107
+ encoding: US-ASCII
108
+ string: ! '{"updatedAt":"2012-09-20T04:31:52.602Z"}'
109
+ http_version:
110
+ recorded_at: Thu, 20 Sep 2012 04:31:52 GMT
111
+ recorded_with: VCR 2.2.4
@@ -0,0 +1,111 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://FKEzdzDgEyghLDFgIVHYJehVlWpfVtUmEv4MUEkJ:bOYO7usWbrcIbL5L5bPzlYrSonQRvwJecC1XLsuN@api.parse.com/1/classes/Post
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{"title":"testing updated_at"}'
9
+ headers:
10
+ Accept:
11
+ - ! '*/*; q=0.5, application/xml'
12
+ Accept-Encoding:
13
+ - gzip, deflate
14
+ Content-Type:
15
+ - application/json
16
+ Content-Length:
17
+ - '30'
18
+ User-Agent:
19
+ - Ruby
20
+ response:
21
+ status:
22
+ code: 201
23
+ message: Created
24
+ headers:
25
+ Access-Control-Allow-Origin:
26
+ - https://parse.com, https://www.parse.com
27
+ Access-Control-Request-Method:
28
+ - ! '*'
29
+ Cache-Control:
30
+ - no-cache
31
+ Content-Type:
32
+ - application/json; charset=utf-8
33
+ Date:
34
+ - Thu, 20 Sep 2012 04:31:52 GMT
35
+ Location:
36
+ - https://api.parse.com/1/classes/Post/cIvspAigOF
37
+ Server:
38
+ - nginx/1.2.2
39
+ Set-Cookie:
40
+ - _parse_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlYjNkNzU1MTRkNGEyNGVlZTIwZGI2N2M2ODMxMTBhNzI%3D--1626b6ac066234b02572edb5290bb349d14fccdd;
41
+ domain=.parse.com; path=/; expires=Tue, 20-Sep-2022 04:31:52 GMT; HttpOnly
42
+ Status:
43
+ - 201 Created
44
+ X-Runtime:
45
+ - '0.055955'
46
+ X-Ua-Compatible:
47
+ - IE=Edge,chrome=1
48
+ Content-Length:
49
+ - '64'
50
+ Connection:
51
+ - keep-alive
52
+ body:
53
+ encoding: US-ASCII
54
+ string: ! '{"createdAt":"2012-09-20T04:31:52.900Z","objectId":"cIvspAigOF"}'
55
+ http_version:
56
+ recorded_at: Thu, 20 Sep 2012 04:31:52 GMT
57
+ - request:
58
+ method: put
59
+ uri: https://FKEzdzDgEyghLDFgIVHYJehVlWpfVtUmEv4MUEkJ:bOYO7usWbrcIbL5L5bPzlYrSonQRvwJecC1XLsuN@api.parse.com/1/classes/Post/cIvspAigOF
60
+ body:
61
+ encoding: UTF-8
62
+ string: ! '{"title":"something else"}'
63
+ headers:
64
+ Accept:
65
+ - ! '*/*; q=0.5, application/xml'
66
+ Accept-Encoding:
67
+ - gzip, deflate
68
+ Content-Type:
69
+ - application/json
70
+ Content-Length:
71
+ - '26'
72
+ User-Agent:
73
+ - Ruby
74
+ response:
75
+ status:
76
+ code: 200
77
+ message: OK
78
+ headers:
79
+ Access-Control-Allow-Origin:
80
+ - https://parse.com, https://www.parse.com
81
+ Access-Control-Request-Method:
82
+ - ! '*'
83
+ Cache-Control:
84
+ - max-age=0, private, must-revalidate
85
+ Content-Type:
86
+ - application/json; charset=utf-8
87
+ Date:
88
+ - Thu, 20 Sep 2012 04:31:53 GMT
89
+ Etag:
90
+ - ! '"d700a1f67eaa78d8c565e23985aa6a14"'
91
+ Server:
92
+ - nginx/1.2.2
93
+ Set-Cookie:
94
+ - _parse_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlMzYwNjkxZDMyZjEzNWM4N2I1NjRhNzJiZDliNTA1YzI%3D--3d52b9803a7ee1d7c8548c1ae1eded40df363646;
95
+ domain=.parse.com; path=/; expires=Tue, 20-Sep-2022 04:31:53 GMT; HttpOnly
96
+ Status:
97
+ - 200 OK
98
+ X-Runtime:
99
+ - '0.027656'
100
+ X-Ua-Compatible:
101
+ - IE=Edge,chrome=1
102
+ Content-Length:
103
+ - '40'
104
+ Connection:
105
+ - keep-alive
106
+ body:
107
+ encoding: US-ASCII
108
+ string: ! '{"updatedAt":"2012-09-20T04:31:53.023Z"}'
109
+ http_version:
110
+ recorded_at: Thu, 20 Sep 2012 04:31:53 GMT
111
+ recorded_with: VCR 2.2.4
@@ -0,0 +1,109 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://FKEzdzDgEyghLDFgIVHYJehVlWpfVtUmEv4MUEkJ:bOYO7usWbrcIbL5L5bPzlYrSonQRvwJecC1XLsuN@api.parse.com/1/users
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{"username":"alan","password":"12345"}'
9
+ headers:
10
+ Accept:
11
+ - ! '*/*; q=0.5, application/xml'
12
+ Accept-Encoding:
13
+ - gzip, deflate
14
+ Content-Type:
15
+ - application/json
16
+ Content-Length:
17
+ - '38'
18
+ User-Agent:
19
+ - Ruby
20
+ response:
21
+ status:
22
+ code: 201
23
+ message: Created
24
+ headers:
25
+ Access-Control-Allow-Origin:
26
+ - https://parse.com, https://www.parse.com
27
+ Access-Control-Request-Method:
28
+ - ! '*'
29
+ Cache-Control:
30
+ - no-cache
31
+ Content-Type:
32
+ - application/json; charset=utf-8
33
+ Date:
34
+ - Thu, 20 Sep 2012 04:31:54 GMT
35
+ Location:
36
+ - https://api.parse.com/1/users/jM7xgj1AAd
37
+ Server:
38
+ - nginx/1.2.2
39
+ Set-Cookie:
40
+ - _parse_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlY2UwYjdjNTRlYzNiMDI4MjU3ZDJmZGIzYTMzNTNmM2U%3D--88ba47ef54acb3b37a15104841ae4759fd63c900;
41
+ domain=.parse.com; path=/; expires=Tue, 20-Sep-2022 04:31:54 GMT; HttpOnly
42
+ Status:
43
+ - 201 Created
44
+ X-Runtime:
45
+ - '0.118062'
46
+ X-Ua-Compatible:
47
+ - IE=Edge,chrome=1
48
+ Content-Length:
49
+ - '107'
50
+ Connection:
51
+ - keep-alive
52
+ body:
53
+ encoding: US-ASCII
54
+ string: ! '{"createdAt":"2012-09-20T04:31:54.750Z","objectId":"jM7xgj1AAd","sessionToken":"g5nayvxbudmlv4usl48zqqu67"}'
55
+ http_version:
56
+ recorded_at: Thu, 20 Sep 2012 04:31:54 GMT
57
+ - request:
58
+ method: post
59
+ uri: https://FKEzdzDgEyghLDFgIVHYJehVlWpfVtUmEv4MUEkJ:bOYO7usWbrcIbL5L5bPzlYrSonQRvwJecC1XLsuN@api.parse.com/1/users
60
+ body:
61
+ encoding: UTF-8
62
+ string: ! '{"username":"alan","password":"56789"}'
63
+ headers:
64
+ Accept:
65
+ - ! '*/*; q=0.5, application/xml'
66
+ Accept-Encoding:
67
+ - gzip, deflate
68
+ Content-Type:
69
+ - application/json
70
+ Content-Length:
71
+ - '38'
72
+ User-Agent:
73
+ - Ruby
74
+ response:
75
+ status:
76
+ code: 400
77
+ message: Bad Request
78
+ headers:
79
+ Access-Control-Allow-Origin:
80
+ - https://parse.com, https://www.parse.com
81
+ Access-Control-Request-Method:
82
+ - ! '*'
83
+ Cache-Control:
84
+ - no-cache
85
+ Content-Type:
86
+ - application/json; charset=utf-8
87
+ Date:
88
+ - Thu, 20 Sep 2012 04:31:55 GMT
89
+ Server:
90
+ - nginx/1.2.2
91
+ Set-Cookie:
92
+ - _parse_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlN2ZjYjE4ZDQ1MzBhNjZiMzE1YWEzMDdiNTlhZGVlMmM%3D--d80414f600539551ebcea5f599a2cc94d246db8e;
93
+ domain=.parse.com; path=/; expires=Tue, 20-Sep-2022 04:31:55 GMT; HttpOnly
94
+ Status:
95
+ - 400 Bad Request
96
+ X-Runtime:
97
+ - '0.020062'
98
+ X-Ua-Compatible:
99
+ - IE=Edge,chrome=1
100
+ Content-Length:
101
+ - '50'
102
+ Connection:
103
+ - keep-alive
104
+ body:
105
+ encoding: US-ASCII
106
+ string: ! '{"code":202,"error":"username alan already taken"}'
107
+ http_version:
108
+ recorded_at: Thu, 20 Sep 2012 04:31:55 GMT
109
+ recorded_with: VCR 2.2.4
@@ -0,0 +1,107 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://FKEzdzDgEyghLDFgIVHYJehVlWpfVtUmEv4MUEkJ:bOYO7usWbrcIbL5L5bPzlYrSonQRvwJecC1XLsuN@api.parse.com/1/classes/Post
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{"title":"Welcome111"}'
9
+ headers:
10
+ Accept:
11
+ - ! '*/*; q=0.5, application/xml'
12
+ Accept-Encoding:
13
+ - gzip, deflate
14
+ Content-Type:
15
+ - application/json
16
+ Content-Length:
17
+ - '22'
18
+ User-Agent:
19
+ - Ruby
20
+ response:
21
+ status:
22
+ code: 201
23
+ message: Created
24
+ headers:
25
+ Access-Control-Allow-Origin:
26
+ - https://parse.com, https://www.parse.com
27
+ Access-Control-Request-Method:
28
+ - ! '*'
29
+ Cache-Control:
30
+ - no-cache
31
+ Content-Type:
32
+ - application/json; charset=utf-8
33
+ Date:
34
+ - Thu, 20 Sep 2012 04:31:53 GMT
35
+ Location:
36
+ - https://api.parse.com/1/classes/Post/3SLqXuGaJK
37
+ Server:
38
+ - nginx/1.2.2
39
+ Set-Cookie:
40
+ - _parse_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlYWY4MzM4NGJiMTAyY2YwMzIyNWY0YmMxZTNkZmJmZDQ%3D--875f08a78a4a12afab58b8701e4786106b06d1e1;
41
+ domain=.parse.com; path=/; expires=Tue, 20-Sep-2022 04:31:53 GMT; HttpOnly
42
+ Status:
43
+ - 201 Created
44
+ X-Runtime:
45
+ - '0.022916'
46
+ X-Ua-Compatible:
47
+ - IE=Edge,chrome=1
48
+ Content-Length:
49
+ - '64'
50
+ Connection:
51
+ - keep-alive
52
+ body:
53
+ encoding: US-ASCII
54
+ string: ! '{"createdAt":"2012-09-20T04:31:53.382Z","objectId":"3SLqXuGaJK"}'
55
+ http_version:
56
+ recorded_at: Thu, 20 Sep 2012 04:31:53 GMT
57
+ - request:
58
+ method: get
59
+ uri: https://FKEzdzDgEyghLDFgIVHYJehVlWpfVtUmEv4MUEkJ:bOYO7usWbrcIbL5L5bPzlYrSonQRvwJecC1XLsuN@api.parse.com/1/classes/Post?where=%7B%22title%22:%22Welcome111%22%7D
60
+ body:
61
+ encoding: US-ASCII
62
+ string: ''
63
+ headers:
64
+ Accept:
65
+ - ! '*/*; q=0.5, application/xml'
66
+ Accept-Encoding:
67
+ - gzip, deflate
68
+ User-Agent:
69
+ - Ruby
70
+ response:
71
+ status:
72
+ code: 200
73
+ message: OK
74
+ headers:
75
+ Access-Control-Allow-Origin:
76
+ - https://parse.com, https://www.parse.com
77
+ Access-Control-Request-Method:
78
+ - ! '*'
79
+ Cache-Control:
80
+ - max-age=0, private, must-revalidate
81
+ Content-Type:
82
+ - application/json; charset=utf-8
83
+ Date:
84
+ - Thu, 20 Sep 2012 04:31:53 GMT
85
+ Etag:
86
+ - ! '"3b1e9ac0dc83a6d8221e794dbede5d29"'
87
+ Server:
88
+ - nginx/1.2.2
89
+ Set-Cookie:
90
+ - _parse_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIlNGVhYzJkODZiNjI4Y2JmNzEzMDA3NjAwMWM2NTVlM2M%3D--c97a9b2b51b0abd4c765c0ee6becd547b3cdb629;
91
+ domain=.parse.com; path=/; expires=Tue, 20-Sep-2022 04:31:53 GMT; HttpOnly
92
+ Status:
93
+ - 200 OK
94
+ X-Runtime:
95
+ - '0.036114'
96
+ X-Ua-Compatible:
97
+ - IE=Edge,chrome=1
98
+ Content-Length:
99
+ - '388'
100
+ Connection:
101
+ - keep-alive
102
+ body:
103
+ encoding: US-ASCII
104
+ string: ! '{"results":[{"title":"Welcome111","createdAt":"2012-09-20T04:31:45.557Z","updatedAt":"2012-09-20T04:31:45.557Z","objectId":"HKWHSsET9H"},{"title":"Welcome111","createdAt":"2012-09-20T04:31:44.836Z","updatedAt":"2012-09-20T04:31:44.836Z","objectId":"ZwjYQFBuv6"},{"title":"Welcome111","createdAt":"2012-09-20T04:31:53.382Z","updatedAt":"2012-09-20T04:31:53.382Z","objectId":"3SLqXuGaJK"}]}'
105
+ http_version:
106
+ recorded_at: Thu, 20 Sep 2012 04:31:53 GMT
107
+ recorded_with: VCR 2.2.4
@@ -140,6 +140,8 @@ module ParseResource
140
140
  result = klass_name.constantize.find(@attributes[k]["objectId"])
141
141
  when "Object"
142
142
  result = klass_name.constantize.new(@attributes[k], false)
143
+ when "File"
144
+ result = @attributes[k]["url"]
143
145
  end #todo: support Dates and other types https://www.parse.com/docs/rest#objects-types
144
146
 
145
147
  else
@@ -156,57 +158,6 @@ module ParseResource
156
158
  create_getters!(k,v)
157
159
  end
158
160
  end
159
-
160
- def self.has_many(children, options = {})
161
- options.stringify_keys!
162
-
163
- parent_klass_name = model_name
164
- lowercase_parent_klass_name = parent_klass_name.downcase
165
- parent_klass = model_name.constantize
166
- child_klass_name = options['class_name'] || children.to_s.singularize.camelize
167
- child_klass = child_klass_name.constantize
168
-
169
- if parent_klass_name == "User"
170
- parent_klass_name = "_User"
171
- end
172
-
173
- @@parent_klass_name = parent_klass_name
174
- @@options ||= {}
175
- @@options[children] ||= {}
176
- @@options[children].merge!(options)
177
-
178
- send(:define_method, children) do
179
- @@parent_id = self.id
180
- @@parent_instance = self
181
-
182
- parent_klass_name = case
183
- when @@options[children]['inverse_of'] then @@options[children]['inverse_of'].downcase
184
- when @@parent_klass_name == "User" then "_User"
185
- else @@parent_klass_name.downcase
186
- end
187
-
188
- query = child_klass.where(parent_klass_name.to_sym => @@parent_instance.to_pointer)
189
- singleton = query.all
190
-
191
- class << singleton
192
- def <<(child)
193
- parent_klass_name = case
194
- when @@options[children]['inverse_of'] then @@options[children]['inverse_of'].downcase
195
- when @@parent_klass_name == "User" then @@parent_klass_name
196
- else @@parent_klass_name.downcase
197
- end
198
- if @@parent_instance.respond_to?(:to_pointer)
199
- child.send("#{parent_klass_name}=", @@parent_instance.to_pointer)
200
- child.save
201
- end
202
- super(child)
203
- end
204
- end
205
-
206
- singleton
207
- end
208
-
209
- end
210
161
 
211
162
  @@settings ||= nil
212
163
 
@@ -250,6 +201,33 @@ module ParseResource
250
201
  RestClient::Resource.new(base_uri, app_id, master_key)
251
202
  end
252
203
 
204
+ # Creates a RESTful resource for file uploads
205
+ # sends requests to [base_uri]/files
206
+ #
207
+ def self.upload(file_instance, filename, options={})
208
+ if @@settings.nil?
209
+ path = "config/parse_resource.yml"
210
+ environment = defined?(Rails) && Rails.respond_to?(:env) ? Rails.env : ENV["RACK_ENV"]
211
+ @@settings = YAML.load(ERB.new(File.new(path).read).result)[environment]
212
+ end
213
+
214
+ base_uri = "https://api.parse.com/1/files"
215
+
216
+ #refactor to settings['app_id'] etc
217
+ app_id = @@settings['app_id']
218
+ master_key = @@settings['master_key']
219
+
220
+ options[:content_type] ||= 'image/jpg' # TODO: Guess mime type here.
221
+ file_instance = File.new(file_instance, 'rb') if file_instance.is_a? String
222
+
223
+ private_resource = RestClient::Resource.new "#{base_uri}/#{filename}", app_id, master_key
224
+ private_resource.post(file_instance, options) do |resp, req, res, &block|
225
+ return false if resp.code == 400
226
+ return JSON.parse(resp)
227
+ end
228
+ false
229
+ end
230
+
253
231
  # Find a ParseResource::Base object by ID
254
232
  #
255
233
  # @param [String] id the ID of the Parse object you want to find.
@@ -296,10 +274,16 @@ module ParseResource
296
274
  def self.limit(n)
297
275
  Query.new(self).limit(n)
298
276
  end
299
-
300
- def self.order(attribute)
301
- Query.new(self).order(attribute)
277
+
278
+ # Skip the number of objects
279
+ #
280
+ def self.skip(n)
281
+ Query.new(self).skip(n)
302
282
  end
283
+
284
+ #def self.order(attribute)
285
+ # Query.new(self).order(attribute)
286
+ #end
303
287
 
304
288
  # Create a ParseResource::Base object.
305
289
  #
@@ -307,7 +291,9 @@ module ParseResource
307
291
  # @return [ParseResource] an object that subclasses `ParseResource`. Or returns `false` if object fails to save.
308
292
  def self.create(attributes = {})
309
293
  attributes = HashWithIndifferentAccess.new(attributes)
310
- new(attributes).save
294
+ obj = new(attributes)
295
+ obj.save
296
+ obj
311
297
  end
312
298
 
313
299
  def self.destroy_all
@@ -355,25 +341,26 @@ module ParseResource
355
341
  error_response = JSON.parse(resp)
356
342
  pe = ParseError.new(error_response["code"]).to_array
357
343
  self.errors.add(pe[0], pe[1])
358
-
344
+ return false
359
345
  else
360
346
  @attributes.merge!(JSON.parse(resp))
361
347
  @attributes.merge!(@unsaved_attributes)
362
348
  attributes = HashWithIndifferentAccess.new(attributes)
363
349
  @unsaved_attributes = {}
364
350
  create_setters_and_getters!
351
+ return true
365
352
  end
366
-
367
- self
368
353
  end
369
-
370
- result
371
354
  end
372
355
 
373
356
  def save
374
357
  if valid?
375
358
  run_callbacks :save do
376
- new? ? create : update
359
+ if new?
360
+ return create
361
+ else
362
+ return update
363
+ end
377
364
  end
378
365
  else
379
366
  false
@@ -395,7 +382,6 @@ module ParseResource
395
382
 
396
383
  opts = {:content_type => "application/json"}
397
384
  result = self.instance_resource.put(put_attrs, opts) do |resp, req, res, &block|
398
-
399
385
  case resp.code
400
386
  when 400
401
387
 
@@ -404,6 +390,7 @@ module ParseResource
404
390
  pe = ParseError.new(error_response["code"], error_response["error"]).to_array
405
391
  self.errors.add(pe[0], pe[1])
406
392
 
393
+ return false
407
394
  else
408
395
 
409
396
  @attributes.merge!(JSON.parse(resp))
@@ -411,12 +398,9 @@ module ParseResource
411
398
  @unsaved_attributes = {}
412
399
  create_setters_and_getters!
413
400
 
414
- self
401
+ return true
415
402
  end
416
-
417
- result
418
403
  end
419
-
420
404
  end
421
405
 
422
406
  def update_attributes(attributes = {})
@@ -424,10 +408,22 @@ module ParseResource
424
408
  end
425
409
 
426
410
  def destroy
427
- self.instance_resource.delete
428
- @attributes = {}
411
+ if self.instance_resource.delete
412
+ @attributes = {}
413
+ @unsaved_attributes = {}
414
+ return true
415
+ end
416
+ false
417
+ end
418
+
419
+ def reload
420
+ return false if new?
421
+
422
+ fresh_object = self.class.find(id)
423
+ @attributes.update(fresh_object.instance_variable_get('@attributes'))
429
424
  @unsaved_attributes = {}
430
- nil
425
+
426
+ self
431
427
  end
432
428
 
433
429
  # provides access to @attributes for getting and setting
@@ -436,6 +432,7 @@ module ParseResource
436
432
  @attributes
437
433
  end
438
434
 
435
+ # AKN 2012-06-18: Shouldn't this also be setting @unsaved_attributes?
439
436
  def attributes=(n)
440
437
  @attributes = n
441
438
  @attributes