parse_resource 1.7.1 → 1.7.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,406 +0,0 @@
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
- require "query"
9
- require "parse_error"
10
-
11
- module ParseResource
12
-
13
-
14
- class Base
15
- # ParseResource::Base provides an easy way to use Ruby to interace with a Parse.com backend
16
- # Usage:
17
- # class Post < ParseResource::Base
18
- # fields :title, :author, :body
19
- # end
20
-
21
- include ActiveModel::Validations
22
- include ActiveModel::Conversion
23
- include ActiveModel::AttributeMethods
24
- extend ActiveModel::Naming
25
- extend ActiveModel::Callbacks
26
- HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess
27
-
28
- define_model_callbacks :save, :create, :update, :destroy
29
-
30
- # Instantiates a ParseResource::Base object
31
- #
32
- # @params [Hash], [Boolean] a `Hash` of attributes and a `Boolean` that should be false only if the object already exists
33
- # @return [ParseResource::Base] an object that subclasses `Parseresource::Base`
34
- def initialize(attributes = {}, new=true)
35
- #attributes = HashWithIndifferentAccess.new(attributes)
36
-
37
- if new
38
- @unsaved_attributes = attributes
39
- else
40
- @unsaved_attributes = {}
41
- end
42
- self.attributes = {}
43
- self.attributes.merge!(attributes)
44
- self.attributes unless self.attributes.empty?
45
- create_setters!
46
- end
47
-
48
- # Explicitly adds a field to the model.
49
- #
50
- # @param [Symbol] name the name of the field, eg `:author`.
51
- # @param [Boolean] val the return value of the field. Only use this within the class.
52
- def self.field(name, val=nil)
53
- class_eval do
54
- define_method(name) do
55
- @attributes[name] ? @attributes[name] : @unsaved_attributes[name]
56
- end
57
- define_method("#{name}=") do |val|
58
- @attributes[name] = val
59
- @unsaved_attributes[name] = val
60
- val
61
- end
62
- end
63
- end
64
-
65
- # Add multiple fields in one line. Same as `#field`, but accepts multiple args.
66
- #
67
- # @param [Array] *args an array of `Symbol`s, `eg :author, :body, :title`.
68
- def self.fields(*args)
69
- args.each {|f| field(f)}
70
- end
71
-
72
- def self.belongs_to(parent)
73
- field(parent)
74
- end
75
-
76
-
77
- def to_pointer
78
- klass_name = self.class.model_name
79
- klass_name = "_User" if klass_name == "User"
80
- {"__type" => "Pointer", "className" => klass_name, "objectId" => self.id}
81
- end
82
-
83
- # Creates getter and setter methods for model fields
84
- #
85
- def create_setters!
86
- @attributes.each_pair do |k,v|
87
-
88
- self.class.send(:define_method, "#{k}=") do |val|
89
- if k.is_a?(Symbol)
90
- k = k.to_s
91
- end
92
-
93
- val = val.to_pointer if val.respond_to?(:to_pointer)
94
-
95
- @attributes[k.to_s] = val
96
- @unsaved_attributes[k.to_s] = val
97
-
98
- val
99
- end
100
-
101
- self.class.send(:define_method, "#{k}") do
102
-
103
- case @attributes[k]
104
- when Hash
105
-
106
- case @attributes[k]["__type"]
107
- when "Pointer"
108
- klass_name = @attributes[k]["className"]
109
- klass_name = "User" if klass_name == "_User"
110
- result = klass_name.constantize.find(@attributes[k]["objectId"])
111
- end #todo: support Dates and other types https://www.parse.com/docs/rest#objects-types
112
-
113
- else
114
- result = @attributes[k]
115
- end
116
-
117
- result
118
- end
119
-
120
- end
121
- end
122
-
123
- class << self
124
-
125
- def has_many(children)
126
- parent_klass_name = model_name
127
- lowercase_parent_klass_name = parent_klass_name.downcase
128
- parent_klass = model_name.constantize
129
- child_klass_name = children.to_s.singularize.camelize
130
- child_klass = child_klass_name.constantize
131
-
132
- if parent_klass_name == "User"
133
- parent_klass_name = "_User"
134
- end
135
-
136
- @@parent_klass_name = parent_klass_name
137
- #@@parent_instance = self
138
-
139
- send(:define_method, children) do
140
- @@parent_id = self.id
141
- @@parent_instance = self
142
-
143
-
144
- singleton = child_klass.where(@@parent_klass_name.downcase => @@parent_instance.to_pointer).all
145
-
146
- class << singleton
147
- def <<(child)
148
- if @@parent_instance.respond_to?(:to_pointer)
149
- child.send("#{@@parent_klass_name.downcase}=", @@parent_instance.to_pointer)
150
- child.save
151
- end
152
- super(child)
153
- end
154
- end
155
-
156
- singleton
157
- end
158
-
159
- end
160
-
161
- @@settings ||= nil
162
-
163
- # Explicitly set Parse.com API keys.
164
- #
165
- # @param [String] app_id the Application ID of your Parse database
166
- # @param [String] master_key the Master Key of your Parse database
167
- def load!(app_id, master_key)
168
- @@settings = {"app_id" => app_id, "master_key" => master_key}
169
- end
170
-
171
- def settings
172
- if @@settings.nil?
173
- path = "config/parse_resource.yml"
174
- #environment = defined?(Rails) && Rails.respond_to?(:env) ? Rails.env : ENV["RACK_ENV"]
175
- environment = ENV["RACK_ENV"]
176
- @@settings = YAML.load(ERB.new(File.new(path).read).result)[environment]
177
- end
178
- @@settings
179
- end
180
-
181
- # Creates a RESTful resource
182
- # sends requests to [base_uri]/[classname]
183
- #
184
- def resource
185
- if @@settings.nil?
186
- path = "config/parse_resource.yml"
187
- environment = defined?(Rails) && Rails.respond_to?(:env) ? Rails.env : ENV["RACK_ENV"]
188
- @@settings = YAML.load(ERB.new(File.new(path).read).result)[environment]
189
- end
190
-
191
- if model_name == "User" #https://parse.com/docs/rest#users-signup
192
- base_uri = "https://api.parse.com/1/users"
193
- else
194
- base_uri = "https://api.parse.com/1/classes/#{model_name}"
195
- end
196
-
197
- #refactor to settings['app_id'] etc
198
- app_id = @@settings['app_id']
199
- master_key = @@settings['master_key']
200
- RestClient::Resource.new(base_uri, app_id, master_key)
201
- end
202
-
203
- # Find a ParseResource::Base object by ID
204
- #
205
- # @param [String] id the ID of the Parse object you want to find.
206
- # @return [ParseResource] an object that subclasses ParseResource.
207
- def find(id)
208
- where(:objectId => id).first
209
- end
210
-
211
- # Find a ParseResource::Base object by chaining #where method calls.
212
- #
213
- def where(*args)
214
- Query.new(self).where(*args)
215
- end
216
-
217
- # Include the attributes of a parent ojbect in the results
218
- # Similar to ActiveRecord eager loading
219
- #
220
- def include_object(parent)
221
- Query.new(self).include_object(parent)
222
- end
223
-
224
- # Add this at the end of a method chain to get the count of objects, instead of an Array of objects
225
- def count
226
- #https://www.parse.com/docs/rest#queries-counting
227
- Query.new(self).count(1)
228
- end
229
-
230
- # Find all ParseResource::Base objects for that model.
231
- #
232
- # @return [Array] an `Array` of objects that subclass `ParseResource`.
233
- def all
234
- Query.new(self).all
235
- end
236
-
237
- # Find the first object. Fairly random, not based on any specific condition.
238
- #
239
- def first
240
- Query.new(self).limit(1).first
241
- end
242
-
243
- # Limits the number of objects returned
244
- #
245
- def limit(n)
246
- Query.new(self).limit(n)
247
- end
248
-
249
- # Create a ParseResource::Base object.
250
- #
251
- # @param [Hash] attributes a `Hash` of attributes
252
- # @return [ParseResource] an object that subclasses `ParseResource`. Or returns `false` if object fails to save.
253
- def create(attributes = {})
254
- attributes = HashWithIndifferentAccess.new(attributes)
255
- new(attributes).save
256
- end
257
-
258
- def destroy_all
259
- all.each do |object|
260
- object.destroy
261
- end
262
- end
263
-
264
- def class_attributes
265
- @class_attributes ||= {}
266
- end
267
-
268
- end
269
-
270
- def persisted?
271
- if id
272
- true
273
- else
274
- false
275
- end
276
- end
277
-
278
- def new?
279
- !persisted?
280
- end
281
-
282
- # delegate from Class method
283
- def resource
284
- self.class.resource
285
- end
286
-
287
- # create RESTful resource for the specific Parse object
288
- # sends requests to [base_uri]/[classname]/[objectId]
289
- def instance_resource
290
- self.class.resource["#{self.id}"]
291
- end
292
-
293
- def create
294
- opts = {:content_type => "application/json"}
295
- attrs = @unsaved_attributes.to_json
296
- result = self.resource.post(attrs, opts) do |resp, req, res, &block|
297
-
298
- case resp.code
299
- when 400
300
-
301
- # https://www.parse.com/docs/ios/api/Classes/PFConstants.html
302
- error_response = JSON.parse(resp)
303
- pe = ParseError.new(error_response["code"]).to_array
304
- self.errors.add(pe[0], pe[1])
305
-
306
- else
307
- @attributes.merge!(JSON.parse(resp))
308
- @attributes.merge!(@unsaved_attributes)
309
- attributes = HashWithIndifferentAccess.new(attributes)
310
- @unsaved_attributes = {}
311
- create_setters!
312
- end
313
-
314
- self
315
- end
316
-
317
- result
318
- end
319
-
320
- def save
321
- if valid?
322
- run_callbacks :save do
323
- new? ? create : update
324
- end
325
- else
326
- false
327
- end
328
- rescue false
329
- end
330
-
331
- def update(attributes = {})
332
-
333
- attributes = HashWithIndifferentAccess.new(attributes)
334
-
335
- @unsaved_attributes.merge!(attributes)
336
-
337
- put_attrs = @unsaved_attributes
338
- put_attrs.delete('objectId')
339
- put_attrs.delete('createdAt')
340
- put_attrs.delete('updatedAt')
341
- put_attrs = put_attrs.to_json
342
-
343
- opts = {:content_type => "application/json"}
344
- result = self.instance_resource.put(put_attrs, opts) do |resp, req, res, &block|
345
-
346
- case resp.code
347
- when 400
348
-
349
- # https://www.parse.com/docs/ios/api/Classes/PFConstants.html
350
- error_response = JSON.parse(resp)
351
- pe = ParseError.new(error_response["code"], error_response["error"]).to_array
352
- self.errors.add(pe[0], pe[1])
353
-
354
- else
355
-
356
- @attributes.merge!(JSON.parse(resp))
357
- @attributes.merge!(@unsaved_attributes)
358
- @unsaved_attributes = {}
359
- create_setters!
360
-
361
- self
362
- end
363
-
364
- result
365
- end
366
-
367
- end
368
-
369
- def update_attributes(attributes = {})
370
- self.update(attributes)
371
- end
372
-
373
- def destroy
374
- self.instance_resource.delete
375
- @attributes = {}
376
- @unsaved_attributes = {}
377
- nil
378
- end
379
-
380
- # provides access to @attributes for getting and setting
381
- def attributes
382
- @attributes ||= self.class.class_attributes
383
- @attributes
384
- end
385
-
386
- def attributes=(n)
387
- @attributes = n
388
- @attributes
389
- end
390
-
391
- # aliasing for idiomatic Ruby
392
- def id; self.objectId rescue nil; end
393
-
394
- def created_at; self.createdAt; end
395
-
396
- def updated_at; self.updatedAt rescue nil; end
397
-
398
- def self.included(base)
399
- base.extend(ClassMethods)
400
- end
401
-
402
- module ClassMethods
403
- end
404
-
405
- end
406
- end
@@ -1,26 +0,0 @@
1
- require 'parse_user_validator'
2
-
3
- class ParseUser < ParseResource::Base
4
- fields :username, :password
5
-
6
- validates_presence_of :username
7
- validates_presence_of :password
8
- #validates_with ParseUserValidator, :on => :create, :on => :save
9
-
10
- def self.authenticate(username, password)
11
- base_uri = "https://api.parse.com/1/login"
12
- app_id = settings['app_id']
13
- master_key = settings['master_key']
14
- resource = RestClient::Resource.new(base_uri, app_id, master_key)
15
-
16
- begin
17
- resp = resource.get(:params => {:username => username, :password => password})
18
- user = model_name.constantize.new(JSON.parse(resp), false)
19
-
20
- user
21
- rescue
22
- false
23
- end
24
-
25
- end
26
- end