Class: ApiResource::Base
- Inherits:
-
Object
- Object
- ApiResource::Base
- Extended by:
- ActiveModel::Naming
- Includes:
- Associations, Attributes, Callbacks, ModelErrors
- Defined in:
- lib/api_resource/base.rb,
lib/api_resource/base.rb
Constant Summary
Constants included from Associations
Associations::ASSOCIATION_TYPES
Instance Attribute Summary collapse
-
#prefix_options ⇒ Object
Returns the value of attribute prefix_options.
Class Method Summary collapse
-
.all(*args) ⇒ Object
This is an alias for find(:all).
- .build(attributes = {}) ⇒ Object
- .collection_path(prefix_options = {}, query_options = nil) ⇒ Object
- .connection(refresh = false) ⇒ Object
- .create(attributes = {}) ⇒ Object
-
.delete(id, options = {}) ⇒ Object
Deletes the resources with the ID in the
id
parameter. -
.element_path(id, prefix_options = {}, query_options = nil) ⇒ Object
alias_method :set_prefix, :prefix= alias_method :set_element_name, :element_name= alias_method :set_collection_name, :collection_name=.
- .find(*arguments) ⇒ Object
-
.first(*args) ⇒ Object
A convenience wrapper for
find(:first, *args)
. -
.format ⇒ Object
Default format is json.
- .format=(mime_type_or_format) ⇒ Object
- .headers ⇒ Object
- .inherited(klass) ⇒ Object
-
.last(*args) ⇒ Object
A convenience wrapper for
find(:last, *args)
. - .new_element_path(prefix_options = {}) ⇒ Object
- .prefix(options = {}) ⇒ Object
- .prefix=(value = '/') ⇒ Object
- .prefix_source ⇒ Object
- .reload_class_attributes ⇒ Object
-
.set_class_attributes_upon_load ⇒ Object
This makes a request to new_element_path.
- .site=(site) ⇒ Object
- .timeout=(timeout) ⇒ Object
Instance Method Summary collapse
- #==(other) ⇒ Object
- #destroy ⇒ Object
- #dup ⇒ Object
- #encode(options = {}) ⇒ Object
- #eql?(other) ⇒ Boolean
- #hash ⇒ Object
- #id ⇒ Object
-
#id=(id) ⇒ Object
Bypass dirty tracking for this field.
-
#initialize(attributes = {}) ⇒ Base
constructor
A new instance of Base.
- #load(attributes) ⇒ Object
- #new? ⇒ Boolean (also: #new_record?)
- #persisted? ⇒ Boolean
- #reload ⇒ Object
- #save(*args) ⇒ Object
- #save!(*args) ⇒ Object
- #serializable_hash(options = {}) ⇒ Object
- #to_json(options = {}) ⇒ Object
-
#to_s ⇒ Object
(also: #inspect)
Override to_s and inspect so they only show attributes and not associations, this prevents force loading of associations when we call to_s or inspect on a descendent of base but allows it if we try to evaluate an association directly.
-
#to_xml(options = {}) ⇒ Object
Methods for serialization as json or xml, relying on the serializable_hash method.
Constructor Details
#initialize(attributes = {}) ⇒ Base
Returns a new instance of Base.
311 312 313 314 |
# File 'lib/api_resource/base.rb', line 311 def initialize(attributes = {}) @prefix_options = {} load(attributes) end |
Instance Attribute Details
#prefix_options ⇒ Object
Returns the value of attribute prefix_options.
17 18 19 |
# File 'lib/api_resource/base.rb', line 17 def @prefix_options end |
Class Method Details
.all(*args) ⇒ Object
This is an alias for find(:all). You can pass in all the same arguments to this method as you can to find(:all)
199 200 201 |
# File 'lib/api_resource/base.rb', line 199 def all(*args) find(:all, *args) end |
.build(attributes = {}) ⇒ Object
161 162 163 |
# File 'lib/api_resource/base.rb', line 161 def build(attributes = {}) self.new(attributes) end |
.collection_path(prefix_options = {}, query_options = nil) ⇒ Object
156 157 158 159 |
# File 'lib/api_resource/base.rb', line 156 def collection_path( = {}, = nil) , = () if .nil? "#{prefix()}#{collection_name}.#{format.extension}#{query_string()}" end |
.connection(refresh = false) ⇒ Object
107 108 109 110 111 |
# File 'lib/api_resource/base.rb', line 107 def connection(refresh = false) @connection = Connection.new(self.site, self.format) if refresh || @connection.nil? @connection.timeout = self.timeout @connection end |
.create(attributes = {}) ⇒ Object
165 166 167 |
# File 'lib/api_resource/base.rb', line 165 def create(attributes = {}) self.new(attributes).tap{ |resource| resource.save } end |
.delete(id, options = {}) ⇒ Object
Deletes the resources with the ID in the id
parameter.
Options
All options specify prefix and query parameters.
Examples
Event.delete(2) # sends DELETE /events/2
Event.create(:name => 'Free Concert', :location => 'Community Center')
my_event = Event.find(:first) # let's assume this is event with ID 7
Event.delete(my_event.id) # sends DELETE /events/7
# Let's assume a request to events/5/cancel.xml
Event.delete(params[:id]) # sends DELETE /events/5
218 219 220 |
# File 'lib/api_resource/base.rb', line 218 def delete(id, = {}) connection.delete(element_path(id, )) end |
.element_path(id, prefix_options = {}, query_options = nil) ⇒ Object
alias_method :set_prefix, :prefix= alias_method :set_element_name, :element_name= alias_method :set_collection_name, :collection_name=
147 148 149 150 |
# File 'lib/api_resource/base.rb', line 147 def element_path(id, = {}, = nil) , = () if .nil? "#{prefix()}#{collection_name}/#{URI.escape id.to_s}.#{format.extension}#{query_string()}" end |
.find(*arguments) ⇒ Object
169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/api_resource/base.rb', line 169 def find(*arguments) scope = arguments.slice!(0) = arguments.slice!(0) || {} case scope when :all then find_every() when :first then find_every().first when :last then find_every().last when :one then find_one() else find_single(scope, ) end end |
.first(*args) ⇒ Object
A convenience wrapper for find(:first, *args)
. You can pass in all the same arguments to this method as you can to find(:first)
.
186 187 188 |
# File 'lib/api_resource/base.rb', line 186 def first(*args) find(:first, *args) end |
.format ⇒ Object
Default format is json
98 99 100 |
# File 'lib/api_resource/base.rb', line 98 def format read_inheritable_attribute(:format) || ApiResource::Formats::JsonFormat end |
.format=(mime_type_or_format) ⇒ Object
91 92 93 94 95 |
# File 'lib/api_resource/base.rb', line 91 def format=(mime_type_or_format) format = mime_type_or_format.is_a?(Symbol) ? ApiResource::Formats[mime_type_or_format] : mime_type_or_format write_inheritable_attribute(:format, format) self.connection.format = format if self.site end |
.headers ⇒ Object
113 114 115 |
# File 'lib/api_resource/base.rb', line 113 def headers @headers || {} end |
.inherited(klass) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/api_resource/base.rb', line 25 def inherited(klass) # Call the methods of the superclass to make sure inheritable accessors and the like have been inherited super # Now we need to define the inherited method on the klass that's doing the inheriting # it calls super which will allow the chaining effect we need klass.instance_eval <<-EOE, __FILE__, __LINE__ + 1 def inherited(klass) super end EOE # Now we can make a call to setup the inheriting klass with its attributes klass.set_class_attributes_upon_load unless klass.instance_variable_defined?(:@class_data) klass.instance_variable_set(:@class_data, true) end |
.last(*args) ⇒ Object
A convenience wrapper for find(:last, *args)
. You can pass in all the same arguments to this method as you can to find(:last)
.
193 194 195 |
# File 'lib/api_resource/base.rb', line 193 def last(*args) find(:last, *args) end |
.new_element_path(prefix_options = {}) ⇒ Object
152 153 154 |
# File 'lib/api_resource/base.rb', line 152 def new_element_path( = {}) "#{prefix()}#{collection_name}/new.#{format.extension}" end |
.prefix(options = {}) ⇒ Object
117 118 119 120 121 122 |
# File 'lib/api_resource/base.rb', line 117 def prefix( = {}) default = (self.site ? self.site.path : '/') default << '/' unless default[-1..-1] == '/' self.prefix = default prefix() end |
.prefix=(value = '/') ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/api_resource/base.rb', line 129 def prefix=(value = '/') prefix_call = value.gsub(/:\w+/) { |key| "\#{URI.escape options[#{key}].to_s}"} @prefix_parameters = nil silence_warnings do instance_eval <<-EOE, __FILE__, __LINE__ + 1 def prefix_source() "#{value}" end def prefix(options={}) "#{prefix_call}" end EOE end rescue Exception => e logger.error "Couldn't set prefix: #{e}\n #{code}" if logger raise end |
.prefix_source ⇒ Object
124 125 126 127 |
# File 'lib/api_resource/base.rb', line 124 def prefix_source prefix prefix_source end |
.reload_class_attributes ⇒ Object
70 71 72 73 74 75 |
# File 'lib/api_resource/base.rb', line 70 def reload_class_attributes # clear the public_attribute_names, protected_attribute_names self.clear_attributes self.clear_associations self.set_class_attributes_upon_load end |
.set_class_attributes_upon_load ⇒ Object
This makes a request to new_element_path
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/api_resource/base.rb', line 42 def set_class_attributes_upon_load begin class_data = self.connection.get(self.new_element_path) # Attributes go first if class_data["attributes"] define_attributes *(class_data["attributes"]["public"] || []) define_protected_attributes *(class_data["attributes"]["protected"] || []) end # Then scopes if class_data["scopes"] class_data["scopes"].each do |hash| self.scope hash.first[0], hash.first[1] end end # Then associations if class_data["associations"] class_data["associations"].each do |(key,hash)| hash.each do |assoc_name, | self.send(key, assoc_name, ) end end end # Swallow up any loading errors because the site may be incorrect rescue Exception => e return nil end end |
.site=(site) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/api_resource/base.rb', line 77 def site=(site) @connection = nil # reset class attributes and try to reload them if the site changed unless site.to_s == self.site.to_s self.reload_class_attributes end if site.nil? write_inheritable_attribute(:site, nil) else write_inheritable_attribute(:site, create_site_uri_from(site)) end end |
.timeout=(timeout) ⇒ Object
102 103 104 105 |
# File 'lib/api_resource/base.rb', line 102 def timeout=(timeout) @connection = nil write_inheritable_attribute(:timeout, timeout) end |
Instance Method Details
#==(other) ⇒ Object
334 335 336 |
# File 'lib/api_resource/base.rb', line 334 def ==(other) other.equal?(self) || (other.instance_of?(self.class) && other.id == self.id && other. == self.) end |
#destroy ⇒ Object
361 362 363 |
# File 'lib/api_resource/base.rb', line 361 def destroy connection.delete(element_path(self.id), self.class.headers) end |
#dup ⇒ Object
346 347 348 349 350 351 |
# File 'lib/api_resource/base.rb', line 346 def dup self.class.new.tap do |resource| resource.attributes = self.attributes resource. = @prefix_options end end |
#encode(options = {}) ⇒ Object
365 366 367 |
# File 'lib/api_resource/base.rb', line 365 def encode( = {}) self.send("to_#{self.class.format.extension}", ) end |
#eql?(other) ⇒ Boolean
338 339 340 |
# File 'lib/api_resource/base.rb', line 338 def eql?(other) self == other end |
#hash ⇒ Object
342 343 344 |
# File 'lib/api_resource/base.rb', line 342 def hash id.hash end |
#id ⇒ Object
325 326 327 |
# File 'lib/api_resource/base.rb', line 325 def id self.attributes[self.class.primary_key] end |
#id=(id) ⇒ Object
Bypass dirty tracking for this field
330 331 332 |
# File 'lib/api_resource/base.rb', line 330 def id=(id) attributes[self.class.primary_key] = id end |
#load(attributes) ⇒ Object
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 |
# File 'lib/api_resource/base.rb', line 373 def load(attributes) return if attributes.nil? raise ArgumentError, "expected an attributes Hash, got #{attributes.inspect}" unless attributes.is_a?(Hash) @prefix_options, attributes = (attributes) attributes.symbolize_keys.each do |key, value| # If this attribute doesn't exist define it as a protected attribute self.class.define_protected_attributes(key) unless self.respond_to?(key) self.attributes[key] = case value when Array if self.has_many?(key) MultiObjectProxy.new(self.has_many_class_name(key), value) elsif self.association?(key) raise ArgumentError, "Expected a hash value or nil, got: #{value.inspect}" else value end when Hash if self.has_many?(key) MultiObjectProxy.new(self.has_many_class_name(key), value) elsif self.association?(key) SingleObjectProxy.new(self.association_class_name(key), value) else value end when NilClass # If it's nil and an association then create a blank object if self.has_many?(key) return MultiObjectProxy.new(self.has_many_class_name(key), []) elsif self.association?(key) SingleObjectProxy.new(self.association_class_name(key), value) end else raise ArgumentError, "expected an array or a hash for the association #{key}, got: #{value.inspect}" if self.association?(key) value.dup rescue value end end return self end |
#new? ⇒ Boolean Also known as: new_record?
316 317 318 |
# File 'lib/api_resource/base.rb', line 316 def new? id.nil? end |
#persisted? ⇒ Boolean
321 322 323 |
# File 'lib/api_resource/base.rb', line 321 def persisted? !new? end |
#reload ⇒ Object
369 370 371 |
# File 'lib/api_resource/base.rb', line 369 def reload self.load(self.class.find(to_param, :params => @prefix_options).attributes) end |
#save(*args) ⇒ Object
353 354 355 |
# File 'lib/api_resource/base.rb', line 353 def save(*args) new? ? create(*args) : update(*args) end |
#save!(*args) ⇒ Object
357 358 359 |
# File 'lib/api_resource/base.rb', line 357 def save!(*args) save(*args) || raise(ApiResource::ResourceInvalid.new(self)) end |
#serializable_hash(options = {}) ⇒ Object
433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 |
# File 'lib/api_resource/base.rb', line 433 def serializable_hash( = {}) [:include_associations] = [:include_associations] ? [:include_associations].symbolize_array : [] [:include_extras] = [:include_extras] ? [:include_extras].symbolize_array : [] [:except] ||= [] ret = self.attributes.inject({}) do |accum, (key,val)| # If this is an association and it's in include_associations then include it if self.association?(key) && [:include_associations].include?(key.to_sym) accum.merge(key => val.serializable_hash({})) elsif [:include_extras].include?(key.to_sym) accum.merge(key => val) elsif [:except].include?(key.to_sym) accum else self.association?(key) || !self.attribute?(key) || self.protected_attribute?(key) ? accum : accum.merge(key => val) end end end |
#to_json(options = {}) ⇒ Object
429 430 431 |
# File 'lib/api_resource/base.rb', line 429 def to_json( = {}) self.class.include_root_in_json ? {self.class.element_name => self.serializable_hash()}.to_json : self.serializable_hash().to_json end |
#to_s ⇒ Object Also known as: inspect
Override to_s and inspect so they only show attributes and not associations, this prevents force loading of associations when we call to_s or inspect on a descendent of base but allows it if we try to evaluate an association directly
418 419 420 |
# File 'lib/api_resource/base.rb', line 418 def to_s return "#<#{self.class}:0x%08x @attributes=#{self.attributes.inject({}){|accum,(k,v)| self.association?(k) ? accum : accum.merge(k => v)}}" % (self.object_id * 2) end |
#to_xml(options = {}) ⇒ Object
Methods for serialization as json or xml, relying on the serializable_hash method
425 426 427 |
# File 'lib/api_resource/base.rb', line 425 def to_xml( = {}) self.serializable_hash().to_xml(:root => self.class.element_name) end |