parse_resource 1.7.1 → 1.7.2

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.
@@ -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