parse_resource 1.5.11 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +36 -7
- data/VERSION +1 -1
- data/lib/base.rb +289 -0
- data/lib/examples/post.rb +4 -8
- data/lib/parse_resource.rb +2 -242
- data/lib/parse_resource_old.rb +286 -0
- data/parse_resource.gemspec +4 -2
- data/rdoc/ParseResource.html +253 -261
- data/rdoc/created.rid +4 -3
- data/rdoc/index.html +5 -7
- data/rdoc/lib/parse_resource_rb.html +16 -2
- data/test/test_parse_resource.rb +2 -2
- metadata +25 -23
data/README.md
CHANGED
@@ -1,16 +1,42 @@
|
|
1
1
|
ParseResource
|
2
2
|
=============
|
3
3
|
|
4
|
-
ParseResource makes it easy to interact with Parse.com's REST API. It adheres to the ActiveRecord pattern. ParceResource is fully ActiveModel compliant, meaning you can use validations
|
4
|
+
ParseResource makes it easy to interact with Parse.com's REST API. It adheres to the ActiveRecord pattern. ParceResource is fully ActiveModel compliant, meaning you can use validations and Rails forms.
|
5
5
|
|
6
6
|
Ruby/Rails developers should feel right at home.
|
7
7
|
|
8
|
+
Features
|
9
|
+
---------------
|
10
|
+
* ActiveRecord-like API, almost no learning curve
|
11
|
+
* Validations
|
12
|
+
* Rails forms and scaffolds **just work**
|
13
|
+
|
14
|
+
Use cases
|
15
|
+
-------------
|
16
|
+
* Build a custom admin dashboard for your Parse.com data
|
17
|
+
* Use the same database for your web and native apps
|
18
|
+
* Pre-collect data for use in iOS and Android apps
|
19
|
+
|
20
|
+
To-do
|
21
|
+
--------------
|
22
|
+
* User authentication
|
23
|
+
* Better documentation
|
24
|
+
* Associations
|
25
|
+
* Callbacks
|
26
|
+
* Push notifications
|
27
|
+
* Better type-casting
|
28
|
+
|
29
|
+
User authentication is my top priority feature. Several people have specifically requested it, and Parse just began exposing [`User` objects in the REST API](https://www.parse.com/docs/rest#users).
|
30
|
+
|
31
|
+
Let me know of any other features you want.
|
32
|
+
|
33
|
+
|
8
34
|
Words of caution
|
9
35
|
---------------
|
10
36
|
|
11
|
-
ParseResource is brand new
|
37
|
+
ParseResource is brand new. Test coverage is decent.
|
12
38
|
|
13
|
-
This is
|
39
|
+
This is my first gem. Be afraid.
|
14
40
|
|
15
41
|
Installation
|
16
42
|
------------
|
@@ -18,7 +44,7 @@ Installation
|
|
18
44
|
Include in your `Gemfile`:
|
19
45
|
|
20
46
|
```ruby
|
21
|
-
gem "parse_resource"
|
47
|
+
gem "parse_resource", "~> 1.5.11"
|
22
48
|
```
|
23
49
|
|
24
50
|
Or just gem install:
|
@@ -59,13 +85,15 @@ Usage
|
|
59
85
|
Create a model:
|
60
86
|
|
61
87
|
```ruby
|
62
|
-
class Post < ParseResource
|
88
|
+
class Post < ParseResource::Base
|
63
89
|
fields :title, :author, :body
|
64
90
|
|
65
91
|
validates_presence_of :title
|
66
92
|
end
|
67
93
|
```
|
68
94
|
|
95
|
+
If you are using version `1.5.11` or earlier, subclass to just `ParseResource`.
|
96
|
+
|
69
97
|
Creating, updating, and deleting:
|
70
98
|
|
71
99
|
```ruby
|
@@ -124,13 +152,14 @@ p = Post.find(id)
|
|
124
152
|
|
125
153
|
Contributing to ParseResource
|
126
154
|
-----------------------------
|
127
|
-
|
155
|
+
|
128
156
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
129
157
|
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
130
158
|
* Fork the project
|
131
159
|
* Start a feature/bugfix branch
|
132
160
|
* Commit and push until you are happy with your contribution
|
133
|
-
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
161
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
162
|
+
* Create `parse_resource.yml` in the root of the gem folder. Using the same format as `parse_resource.yml` in the instructions (except only creating a `test` environment, add your own API keys.
|
134
163
|
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
135
164
|
|
136
165
|
Copyright
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.6.0
|
data/lib/base.rb
ADDED
@@ -0,0 +1,289 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
require "active_model"
|
4
|
+
require "erb"
|
5
|
+
require "rest-client"
|
6
|
+
require "json"
|
7
|
+
require "active_support/hash_with_indifferent_access"
|
8
|
+
|
9
|
+
module ParseResource
|
10
|
+
|
11
|
+
class Base
|
12
|
+
# ParseResource::Base provides an easy way to use Ruby to interace with a Parse.com backend
|
13
|
+
# Usage:
|
14
|
+
# class Post < ParseResource::Base
|
15
|
+
# fields :title, :author, :body
|
16
|
+
# end
|
17
|
+
|
18
|
+
include ActiveModel::Validations
|
19
|
+
include ActiveModel::Conversion
|
20
|
+
include ActiveModel::AttributeMethods
|
21
|
+
extend ActiveModel::Naming
|
22
|
+
extend ActiveModel::Callbacks
|
23
|
+
HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess
|
24
|
+
|
25
|
+
# define_model_callbacks :initialize, :find, :only => :after
|
26
|
+
define_model_callbacks :save, :create, :update, :destroy
|
27
|
+
|
28
|
+
|
29
|
+
# Instantiates a ParseResource::Base object
|
30
|
+
#
|
31
|
+
# @params [Hash], [Boolean] a `Hash` of attributes and a `Boolean` that should be false only if the object already exists
|
32
|
+
# @return [ParseResource::Base] an object that subclasses `Parseresource::Base`
|
33
|
+
def initialize(attributes = {}, new=true)
|
34
|
+
attributes = HashWithIndifferentAccess.new(attributes)
|
35
|
+
if new
|
36
|
+
@unsaved_attributes = attributes
|
37
|
+
else
|
38
|
+
@unsaved_attributes = {}
|
39
|
+
end
|
40
|
+
self.attributes = {}
|
41
|
+
self.attributes.merge!(attributes)
|
42
|
+
self.attributes unless self.attributes.empty?
|
43
|
+
create_setters!
|
44
|
+
end
|
45
|
+
|
46
|
+
# Explicitly adds a field to the model.
|
47
|
+
#
|
48
|
+
# @param [Symbol] name the name of the field, eg `:author`.
|
49
|
+
# @param [Boolean] val the return value of the field. Only use this within the class.
|
50
|
+
def self.field(name, val=nil)
|
51
|
+
class_eval do
|
52
|
+
define_method(name) do
|
53
|
+
@attributes[name] ? @attributes[name] : @unsaved_attributes[name]
|
54
|
+
end
|
55
|
+
define_method("#{name}=") do |val|
|
56
|
+
@attributes[name] = val
|
57
|
+
@unsaved_attributes[name] = val
|
58
|
+
val
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Add multiple fields in one line. Same as `#field`, but accepts multiple args.
|
64
|
+
#
|
65
|
+
# @param [Array] *args an array of `Symbol`s, `eg :author, :body, :title`.
|
66
|
+
def self.fields(*args)
|
67
|
+
args.each {|f| field(f)}
|
68
|
+
end
|
69
|
+
|
70
|
+
# Creates getter and setter methods for model fields
|
71
|
+
#
|
72
|
+
def create_setters!
|
73
|
+
@attributes.each_pair do |k,v|
|
74
|
+
self.class.send(:define_method, "#{k}=") do |val|
|
75
|
+
if k.is_a?(Symbol)
|
76
|
+
k = k.to_s
|
77
|
+
end
|
78
|
+
@attributes[k.to_s] = val
|
79
|
+
@unsaved_attributes[k.to_s] = val
|
80
|
+
val
|
81
|
+
end
|
82
|
+
self.class.send(:define_method, "#{k}") do
|
83
|
+
if k.is_a?(Symbol)
|
84
|
+
k = k.to_s
|
85
|
+
end
|
86
|
+
|
87
|
+
@attributes[k.to_s]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class << self
|
93
|
+
def has_one(child_name)
|
94
|
+
class_eval do
|
95
|
+
|
96
|
+
define_method("#{child_name}") do
|
97
|
+
child_name
|
98
|
+
end
|
99
|
+
|
100
|
+
define_method("#{child_name}=") do |child_object|
|
101
|
+
[child_object, child_name]
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def belongs_to(name)
|
108
|
+
class_eval do
|
109
|
+
|
110
|
+
define_method("#{parent_name}") do
|
111
|
+
name
|
112
|
+
end
|
113
|
+
|
114
|
+
define_method("#{parent_name}=") do |parent_object|
|
115
|
+
[parent_name, parent_object]
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
@@settings ||= nil
|
123
|
+
|
124
|
+
# Explicitly set Parse.com API keys.
|
125
|
+
#
|
126
|
+
# @param [String] app_id the Application ID of your Parse database
|
127
|
+
# @param [String] master_key the Master Key of your Parse database
|
128
|
+
def load!(app_id, master_key)
|
129
|
+
@@settings = {"app_id" => app_id, "master_key" => master_key}
|
130
|
+
end
|
131
|
+
|
132
|
+
# Creates a RESTful resource
|
133
|
+
# sends requests to [base_uri]/[classname]
|
134
|
+
#
|
135
|
+
def resource
|
136
|
+
if @@settings.nil?
|
137
|
+
path = "config/parse_resource.yml"
|
138
|
+
environment = defined?(Rails) && Rails.respond_to?(:env) ? Rails.env : ENV["RACK_ENV"]
|
139
|
+
@@settings = YAML.load(ERB.new(File.new(path).read).result)[environment]
|
140
|
+
end
|
141
|
+
base_uri = "https://api.parse.com/1/classes/#{model_name}"
|
142
|
+
app_id = @@settings['app_id']
|
143
|
+
master_key = @@settings['master_key']
|
144
|
+
RestClient::Resource.new(base_uri, app_id, master_key)
|
145
|
+
end
|
146
|
+
|
147
|
+
# Find a ParseResource::Baseobject by ID
|
148
|
+
#
|
149
|
+
# @param [String] id the ID of the Parse object you want to find.
|
150
|
+
# @return [ParseResource] an object that subclasses ParseResource.
|
151
|
+
def find(id)
|
152
|
+
where(:objectId => id).first
|
153
|
+
end
|
154
|
+
|
155
|
+
# Find a ParseResource::Baseobject by a `Hash` of conditions.
|
156
|
+
#
|
157
|
+
# @param [Hash] parameters a `Hash` of conditions.
|
158
|
+
# @return [Array] an `Array` of objects that subclass `ParseResource`.
|
159
|
+
def where(parameters)
|
160
|
+
resp = resource.get(:params => {:where => parameters.to_json})
|
161
|
+
results = JSON.parse(resp)['results']
|
162
|
+
results.map {|r| model_name.constantize.new(r, false)}
|
163
|
+
end
|
164
|
+
|
165
|
+
# Find all ParseResource::Baseobjects for that model.
|
166
|
+
#
|
167
|
+
# @return [Array] an `Array` of objects that subclass `ParseResource`.
|
168
|
+
def all
|
169
|
+
resp = resource.get
|
170
|
+
results = JSON.parse(resp)['results']
|
171
|
+
results.map {|r| model_name.constantize.new(r, false)}
|
172
|
+
end
|
173
|
+
|
174
|
+
# Create a ParseResource::Baseobject.
|
175
|
+
#
|
176
|
+
# @param [Hash] attributes a `Hash` of attributes
|
177
|
+
# @return [ParseResource] an object that subclasses `ParseResource`. Or returns `false` if object fails to save.
|
178
|
+
def create(attributes = {})
|
179
|
+
attributes = HashWithIndifferentAccess.new(attributes)
|
180
|
+
new(attributes).save
|
181
|
+
end
|
182
|
+
|
183
|
+
# Find the first object. Fairly random, not based on any specific condition.
|
184
|
+
#
|
185
|
+
def first
|
186
|
+
all.first
|
187
|
+
end
|
188
|
+
|
189
|
+
def class_attributes
|
190
|
+
@class_attributes ||= {}
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
def persisted?
|
196
|
+
if id
|
197
|
+
true
|
198
|
+
else
|
199
|
+
false
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def new?
|
204
|
+
!persisted?
|
205
|
+
end
|
206
|
+
|
207
|
+
# delegate from Class method
|
208
|
+
def resource
|
209
|
+
self.class.resource
|
210
|
+
end
|
211
|
+
|
212
|
+
# create RESTful resource for the specific Parse object
|
213
|
+
# sends requests to [base_uri]/[classname]/[objectId]
|
214
|
+
def instance_resource
|
215
|
+
self.class.resource["#{self.id}"]
|
216
|
+
end
|
217
|
+
|
218
|
+
def create
|
219
|
+
resp = self.resource.post(@unsaved_attributes.to_json, :content_type => "application/json")
|
220
|
+
@attributes.merge!(JSON.parse(resp))
|
221
|
+
@attributes.merge!(@unsaved_attributes)
|
222
|
+
attributes = HashWithIndifferentAccess.new(attributes)
|
223
|
+
@unsaved_attributes = {}
|
224
|
+
create_setters!
|
225
|
+
self
|
226
|
+
end
|
227
|
+
|
228
|
+
def save
|
229
|
+
if valid?
|
230
|
+
run_callbacks :save do
|
231
|
+
new? ? create : update
|
232
|
+
end
|
233
|
+
else
|
234
|
+
false
|
235
|
+
end
|
236
|
+
rescue false
|
237
|
+
end
|
238
|
+
|
239
|
+
def update(attributes = {})
|
240
|
+
attributes = HashWithIndifferentAccess.new(attributes)
|
241
|
+
@unsaved_attributes.merge!(attributes)
|
242
|
+
|
243
|
+
put_attrs = @unsaved_attributes
|
244
|
+
put_attrs.delete('objectId')
|
245
|
+
put_attrs.delete('createdAt')
|
246
|
+
put_attrs.delete('updatedAt')
|
247
|
+
put_attrs = put_attrs.to_json
|
248
|
+
|
249
|
+
resp = self.instance_resource.put(put_attrs, :content_type => "application/json")
|
250
|
+
|
251
|
+
@attributes.merge!(JSON.parse(resp))
|
252
|
+
@attributes.merge!(@unsaved_attributes)
|
253
|
+
@unsaved_attributes = {}
|
254
|
+
create_setters!
|
255
|
+
|
256
|
+
self
|
257
|
+
end
|
258
|
+
|
259
|
+
def update_attributes(attributes = {})
|
260
|
+
self.update(attributes)
|
261
|
+
end
|
262
|
+
|
263
|
+
def destroy
|
264
|
+
self.instance_resource.delete
|
265
|
+
@attributes = {}
|
266
|
+
@unsaved_attributes = {}
|
267
|
+
nil
|
268
|
+
end
|
269
|
+
|
270
|
+
# provides access to @attributes for getting and setting
|
271
|
+
def attributes
|
272
|
+
@attributes ||= self.class.class_attributes
|
273
|
+
@attributes
|
274
|
+
end
|
275
|
+
|
276
|
+
def attributes=(n)
|
277
|
+
@attributes = n
|
278
|
+
@attributes
|
279
|
+
end
|
280
|
+
|
281
|
+
# aliasing for idiomatic Ruby
|
282
|
+
def id; self.objectId rescue nil; end
|
283
|
+
|
284
|
+
def created_at; self.createdAt; end
|
285
|
+
|
286
|
+
def updated_at; self.updatedAt rescue nil; end
|
287
|
+
|
288
|
+
end
|
289
|
+
end
|
data/lib/examples/post.rb
CHANGED
@@ -1,15 +1,11 @@
|
|
1
|
+
require 'helper'
|
1
2
|
require 'parse_resource'
|
2
|
-
require 'pp'
|
3
3
|
|
4
|
+
path = "parse_resource.yml"
|
5
|
+
settings = YAML.load(ERB.new(File.new(path).read).result)['test']
|
4
6
|
|
5
|
-
ParseResource.load!(
|
7
|
+
ParseResource.load!(settings['app_id'], settings['master_key'])
|
6
8
|
|
7
9
|
class Post < ParseResource
|
8
10
|
fields :title, :author, :body
|
9
|
-
|
10
|
-
after_save :add_author
|
11
|
-
|
12
|
-
def add_author
|
13
|
-
update(:author => "Alan")
|
14
|
-
end
|
15
11
|
end
|
data/lib/parse_resource.rb
CHANGED
@@ -1,244 +1,4 @@
|
|
1
|
-
require
|
2
|
-
require "bundler/setup"
|
3
|
-
require "active_model"
|
4
|
-
require "erb"
|
5
|
-
require "rest-client"
|
6
|
-
require "json"
|
7
|
-
require "active_support/hash_with_indifferent_access"
|
1
|
+
require 'base'
|
8
2
|
|
9
|
-
|
10
|
-
|
11
|
-
class ParseResource
|
12
|
-
# ParseResource provides an easy way to use Ruby to interace with a Parse.com backend
|
13
|
-
# Usage:
|
14
|
-
# class Post < ParseResource
|
15
|
-
# fields :title, :author, :body
|
16
|
-
# end
|
17
|
-
|
18
|
-
include ActiveModel::Validations
|
19
|
-
include ActiveModel::Conversion
|
20
|
-
include ActiveModel::AttributeMethods
|
21
|
-
extend ActiveModel::Naming
|
22
|
-
extend ActiveModel::Callbacks
|
23
|
-
HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess
|
24
|
-
|
25
|
-
#define_model_callbacks :initialize, :find, :only => :after
|
26
|
-
define_model_callbacks :save, :create, :update, :destroy
|
27
|
-
|
28
|
-
# instantiation!
|
29
|
-
# p = Post.new(:title => "cool story")
|
30
|
-
def initialize(attributes = {}, new=true)
|
31
|
-
attributes = HashWithIndifferentAccess.new(attributes)
|
32
|
-
if new
|
33
|
-
@unsaved_attributes = attributes
|
34
|
-
else
|
35
|
-
@unsaved_attributes = {}
|
36
|
-
end
|
37
|
-
self.attributes = {}
|
38
|
-
self.attributes.merge!(attributes)
|
39
|
-
self.attributes unless self.attributes.empty?
|
40
|
-
create_setters!
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.field(name, val=nil)
|
44
|
-
class_eval do
|
45
|
-
define_method(name) do
|
46
|
-
@attributes[name] ? @attributes[name] : @unsaved_attributes[name]
|
47
|
-
end
|
48
|
-
define_method("#{name}=") do |val|
|
49
|
-
@attributes[name] = val
|
50
|
-
@unsaved_attributes[name] = val
|
51
|
-
val
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def self.fields(*args)
|
57
|
-
args.each {|f| field(f)}
|
58
|
-
end
|
59
|
-
|
60
|
-
# a sprinkle of metaprogramming
|
61
|
-
# p = Post.new(:some_attr => "some value")
|
62
|
-
# p.some_attr = "new value"
|
63
|
-
def create_setters!
|
64
|
-
@attributes.each_pair do |k,v|
|
65
|
-
self.class.send(:define_method, "#{k}=") do |val|
|
66
|
-
if k.is_a?(Symbol)
|
67
|
-
k = k.to_s
|
68
|
-
end
|
69
|
-
@attributes[k.to_s] = val
|
70
|
-
@unsaved_attributes[k.to_s] = val
|
71
|
-
val
|
72
|
-
end
|
73
|
-
self.class.send(:define_method, "#{k}") do
|
74
|
-
if k.is_a?(Symbol)
|
75
|
-
k = k.to_s
|
76
|
-
end
|
77
|
-
|
78
|
-
@attributes[k.to_s]
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
class << self
|
84
|
-
@@settings ||= nil
|
85
|
-
|
86
|
-
def load!(app_id, master_key)
|
87
|
-
@@settings = {"app_id" => app_id, "master_key" => master_key}
|
88
|
-
end
|
89
|
-
|
90
|
-
# creates a RESTful resource
|
91
|
-
# sends requests to [base_uri]/[classname]
|
92
|
-
def resource
|
93
|
-
if @@settings.nil?
|
94
|
-
path = "config/parse_resource.yml"
|
95
|
-
environment = defined?(Rails) && Rails.respond_to?(:env) ? Rails.env : ENV["RACK_ENV"]
|
96
|
-
@@settings = YAML.load(ERB.new(File.new(path).read).result)[environment]
|
97
|
-
end
|
98
|
-
base_uri = "https://api.parse.com/1/classes/#{model_name}"
|
99
|
-
app_id = @@settings['app_id']
|
100
|
-
master_key = @@settings['master_key']
|
101
|
-
RestClient::Resource.new(base_uri, app_id, master_key)
|
102
|
-
end
|
103
|
-
|
104
|
-
# finders
|
105
|
-
# Post.find("abcdf")
|
106
|
-
def find(id)
|
107
|
-
where(:objectId => id).first
|
108
|
-
end
|
109
|
-
|
110
|
-
# Post.where(:author => "Alan", :title => "Ipso Lorem")
|
111
|
-
def where(parameters)
|
112
|
-
resp = resource.get(:params => {:where => parameters.to_json})
|
113
|
-
results = JSON.parse(resp)['results']
|
114
|
-
results.map {|r| model_name.constantize.new(r, false)}
|
115
|
-
end
|
116
|
-
|
117
|
-
# Post.all
|
118
|
-
def all
|
119
|
-
resp = resource.get
|
120
|
-
results = JSON.parse(resp)['results']
|
121
|
-
results.map {|r| model_name.constantize.new(r, false)}
|
122
|
-
end
|
123
|
-
|
124
|
-
# Post.create(:title => "new post")
|
125
|
-
def create(attributes = {})
|
126
|
-
attributes = HashWithIndifferentAccess.new(attributes)
|
127
|
-
new(attributes).save
|
128
|
-
end
|
129
|
-
|
130
|
-
# Post.first
|
131
|
-
def first
|
132
|
-
all.first
|
133
|
-
end
|
134
|
-
|
135
|
-
def class_attributes
|
136
|
-
@class_attributes ||= {}
|
137
|
-
end
|
138
|
-
|
139
|
-
end
|
140
|
-
|
141
|
-
def persisted?
|
142
|
-
if id
|
143
|
-
true
|
144
|
-
else
|
145
|
-
false
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def new?
|
150
|
-
!persisted?
|
151
|
-
end
|
152
|
-
|
153
|
-
# delegate from Class method
|
154
|
-
def resource
|
155
|
-
self.class.resource
|
156
|
-
end
|
157
|
-
|
158
|
-
# create RESTful resource for the specific Parse object
|
159
|
-
# sends requests to [base_uri]/[classname]/[objectId]
|
160
|
-
def instance_resource
|
161
|
-
self.class.resource["#{self.id}"]
|
162
|
-
end
|
163
|
-
|
164
|
-
def create
|
165
|
-
resp = self.resource.post(@unsaved_attributes.to_json, :content_type => "application/json")
|
166
|
-
@attributes.merge!(JSON.parse(resp))
|
167
|
-
@attributes.merge!(@unsaved_attributes)
|
168
|
-
attributes = HashWithIndifferentAccess.new(attributes)
|
169
|
-
@unsaved_attributes = {}
|
170
|
-
create_setters!
|
171
|
-
self
|
172
|
-
end
|
173
|
-
|
174
|
-
def save
|
175
|
-
if valid?
|
176
|
-
run_callbacks :save do
|
177
|
-
new? ? create : update
|
178
|
-
end
|
179
|
-
else
|
180
|
-
false
|
181
|
-
end
|
182
|
-
rescue false
|
183
|
-
end
|
184
|
-
|
185
|
-
def update(attributes = {})
|
186
|
-
attributes = HashWithIndifferentAccess.new(attributes)
|
187
|
-
@unsaved_attributes.merge!(attributes)
|
188
|
-
|
189
|
-
put_attrs = @unsaved_attributes
|
190
|
-
put_attrs.delete('objectId')
|
191
|
-
put_attrs.delete('createdAt')
|
192
|
-
put_attrs.delete('updatedAt')
|
193
|
-
put_attrs = put_attrs.to_json
|
194
|
-
|
195
|
-
resp = self.instance_resource.put(put_attrs, :content_type => "application/json")
|
196
|
-
|
197
|
-
@attributes.merge!(JSON.parse(resp))
|
198
|
-
@attributes.merge!(@unsaved_attributes)
|
199
|
-
@unsaved_attributes = {}
|
200
|
-
create_setters!
|
201
|
-
|
202
|
-
self
|
203
|
-
end
|
204
|
-
|
205
|
-
def update_attributes(attributes = {})
|
206
|
-
self.update(attributes)
|
207
|
-
end
|
208
|
-
|
209
|
-
def destroy
|
210
|
-
self.instance_resource.delete
|
211
|
-
@attributes = {}
|
212
|
-
@unsaved_attributes = {}
|
213
|
-
nil
|
214
|
-
end
|
215
|
-
|
216
|
-
# provides access to @attributes for getting and setting
|
217
|
-
def attributes
|
218
|
-
@attributes ||= self.class.class_attributes
|
219
|
-
@attributes
|
220
|
-
end
|
221
|
-
|
222
|
-
def attributes=(n)
|
223
|
-
@attributes = n
|
224
|
-
@attributes
|
225
|
-
end
|
226
|
-
|
227
|
-
# aliasing for idiomatic Ruby
|
228
|
-
def id; self.objectId rescue nil; end
|
229
|
-
|
230
|
-
def created_at; self.createdAt; end
|
231
|
-
|
232
|
-
def updated_at; self.updatedAt rescue nil; end
|
233
|
-
|
234
|
-
# another sprinkle of metaprogramming
|
235
|
-
# p = Post.new(:some_attr => "some value")
|
236
|
-
# p.some_attr #=> "some value"
|
237
|
-
#def method_missing(meth, *args, &block)
|
238
|
-
# if @attributes.has_key?(meth.to_s)
|
239
|
-
# @attributes[meth.to_s]
|
240
|
-
# else
|
241
|
-
# super
|
242
|
-
# end
|
243
|
-
#end
|
3
|
+
module ParseResource
|
244
4
|
end
|