Class: HyperResource
- Inherits:
-
Object
- Object
- HyperResource
- Includes:
- Modules::HTTP, Modules::Utils
- Defined in:
- lib/hyper_resource.rb,
lib/hyper_resource/links.rb,
lib/hyper_resource/adapter.rb,
lib/hyper_resource/objects.rb,
lib/hyper_resource/version.rb,
lib/hyper_resource/attributes.rb,
lib/hyper_resource/exceptions.rb,
lib/hyper_resource/modules/http.rb,
lib/hyper_resource/adapter/hal_json.rb
Defined Under Namespace
Modules: Modules Classes: Adapter, Attributes, ClientError, Exception, Link, Links, Objects, Response, ResponseError, ServerError
Constant Summary collapse
- DEFAULT_HEADERS =
:nodoc:
{ 'Accept' => 'application/json' }
- VERSION =
'0.1.9.5'- VERSION_DATE =
'2013-10-11'
Class Method Summary collapse
-
._get_response_class(response, namespace) ⇒ Object
Returns the class into which the given response should be cast.
-
._get_response_data_type(response) ⇒ Object
Inspects the given response, and returns a string describing this resource’s data type.
Instance Method Summary collapse
-
#[](i) ⇒ Object
Returns the *i*th object in the first collection of objects embedded in this resource.
-
#_get_response_class ⇒ Object
:nodoc:.
-
#_get_response_data_type ⇒ Object
:nodoc:.
-
#_new_from_link(href) ⇒ Object
Return a new HyperResource based on this object and a given href.
-
#changed?(*args) ⇒ Boolean
Returns true if one or more of this object’s attributes has been reassigned.
-
#first ⇒ Object
Returns the first object in the first collection of objects embedded in this resource.
-
#incoming_body_filter(attr_hash) ⇒ Object
incoming_body_filterfilters a hash of attribute keys and values on their way from a response body to a HyperResource. -
#initialize(opts = {}) ⇒ HyperResource
constructor
Create a new HyperResource, given a hash of options.
-
#inspect ⇒ Object
:nodoc:.
-
#method_missing(method, *args) ⇒ Object
method_missing will load this resource if not yet loaded, then attempt to delegate to
attributes, thenobjects, thenlinks. -
#outgoing_body_filter(attr_hash) ⇒ Object
outgoing_body_filterfilters a hash of attribute keys and values on their way from a HyperResource to a request body. -
#outgoing_uri_filter(attr_hash) ⇒ Object
outgoing_uri_filterfilters a hash of attribute keys and values on their way from a HyperResource to a URL. -
#response_body ⇒ Object
response_bodyis deprecated in favor ofresponse_object.
Methods included from Modules::HTTP
#create, #delete, #faraday_connection, #get, #post, #put, #update
Methods included from Modules::Utils
Constructor Details
#initialize(opts = {}) ⇒ HyperResource
Create a new HyperResource, given a hash of options. These options include:
- root
-
The root URL of the resource.
- auth
-
Authentication information. Currently only {basic: [‘key’, ‘secret’]} is supported.
- namespace
-
Class or class name, into which resources should be instantiated.
- headers
-
Headers to send along with requests for this resource (as well as its eventual child resources, if any).
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/hyper_resource.rb', line 69 def initialize(opts={}) return init_from_resource(opts) if opts.kind_of?(HyperResource) self.root = opts[:root] || self.class.root self.href = opts[:href] || '' self.auth = (self.class.auth || {}).merge(opts[:auth] || {}) self.namespace = opts[:namespace] || self.class.namespace self.headers = DEFAULT_HEADERS.merge(self.class.headers || {}). merge(opts[:headers] || {}) ## There's a little acrobatics in getting Attributes, Links, and Objects ## into the correct subclass. if self.class != HyperResource if self.class::Attributes == HyperResource::Attributes Object.module_eval( "class #{self.class}::Attributes < HyperResource::Attributes; end" ) end if self.class::Links == HyperResource::Links Object.module_eval( "class #{self.class}::Links < HyperResource::Links; end" ) end if self.class::Objects == HyperResource::Objects Object.module_eval( "class #{self.class}::Objects < HyperResource::Objects; end" ) end end self.attributes = self.class::Attributes.new(self) self.links = self.class::Links.new(self) self.objects = self.class::Objects.new(self) self.loaded = false self.adapter = opts[:adapter] || self.class.adapter || HyperResource::Adapter::HAL_JSON end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object
method_missing will load this resource if not yet loaded, then attempt to delegate to attributes, then objects, then links. Override with care.
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/hyper_resource.rb', line 152 def method_missing(method, *args) self.get unless self.loaded method = method.to_s if method[-1,1] == '=' return attributes[method[0..-2]] = args.first if attributes[method[0..-2]] else return attributes[method] if attributes && attributes[method] return objects[method] if objects && objects[method] if links && links[method] if args.count > 0 return links[method].where(*args) else return links[method] end end end raise NoMethodError, "undefined method `#{method}' for #{self.inspect}" end |
Class Method Details
._get_response_class(response, namespace) ⇒ Object
Returns the class into which the given response should be cast. If the object is not loaded yet, or if opts[:namespace] is not set, returns self.
Otherwise, _get_response_class uses _get_response_data_type to determine subclass name, glues it to the given namespace, and creates the class if it’s not there yet. E.g., given a namespace of FooAPI and a response content-type of “application/vnd.foocorp.fooapi.v1+json;type=User”, this should return FooAPI::User (even if FooAPI::User hadn’t existed yet).
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/hyper_resource.rb', line 210 def self._get_response_class(response, namespace) # :nodoc: if self.to_s == 'HyperResource' return self unless namespace end namespace ||= self.to_s type_name = self._get_response_data_type(response) return self unless type_name class_name = "#{namespace}::#{type_name}" class_name.gsub!(/[^_0-9A-Za-z:]/, '') ## sanitize class_name ## Return data type class if it exists klass = eval(class_name) rescue :sorry_dude return klass if klass.is_a?(Class) ## Data type class didn't exist -- create namespace (if necessary), ## then the data type class if namespace != '' nsc = eval(namespace) rescue :bzzzzzt unless nsc.is_a?(Class) Object.module_eval "class #{namespace} < #{self}; end" end end Object.module_eval "class #{class_name} < #{namespace}; end" eval(class_name) end |
._get_response_data_type(response) ⇒ Object
Inspects the given response, and returns a string describing this resource’s data type.
By default, this method looks for a type=… modifier in the response’s Content-type and returns that value, capitalized.
Override this method in a subclass to alter HyperResource’s behavior.
253 254 255 256 257 258 |
# File 'lib/hyper_resource.rb', line 253 def self._get_response_data_type(response) # :nodoc: return nil unless response return nil unless content_type = response['content-type'] return nil unless m=content_type.match(/;\s* type=([0-9A-Za-z:]+)/x) m[1][0,1].upcase + m[1][1..-1] end |
Instance Method Details
#[](i) ⇒ Object
Returns the *i*th object in the first collection of objects embedded in this resource. Equivalent to self.objects[i].
147 |
# File 'lib/hyper_resource.rb', line 147 def [](i); self.objects.ith(i) end |
#_get_response_class ⇒ Object
:nodoc:
239 240 241 242 |
# File 'lib/hyper_resource.rb', line 239 def _get_response_class # :nodoc: self.namespace ||= self.class.to_s unless self.class.to_s=='HyperResource' self.class._get_response_class(self.response, self.namespace) end |
#_get_response_data_type ⇒ Object
:nodoc:
260 261 262 |
# File 'lib/hyper_resource.rb', line 260 def _get_response_data_type # :nodoc: self.class._get_response_data_type(self.response) end |
#_new_from_link(href) ⇒ Object
Return a new HyperResource based on this object and a given href.
190 191 192 193 194 195 196 |
# File 'lib/hyper_resource.rb', line 190 def _new_from_link(href) # :nodoc: self.class.new(:root => self.root, :auth => self.auth, :headers => self.headers, :namespace => self.namespace, :href => href) end |
#changed?(*args) ⇒ Boolean
Returns true if one or more of this object’s attributes has been reassigned.
114 115 116 |
# File 'lib/hyper_resource.rb', line 114 def changed?(*args) attributes.changed?(*args) end |
#first ⇒ Object
Returns the first object in the first collection of objects embedded in this resource. Equivalent to self.objects.first.
143 |
# File 'lib/hyper_resource.rb', line 143 def first; self.objects.first end |
#incoming_body_filter(attr_hash) ⇒ Object
incoming_body_filter filters a hash of attribute keys and values on their way from a response body to a HyperResource. Override this in a subclass of HyperResource to implement filters on incoming data.
121 122 123 |
# File 'lib/hyper_resource.rb', line 121 def incoming_body_filter(attr_hash) attr_hash end |
#inspect ⇒ Object
:nodoc:
174 175 176 177 178 |
# File 'lib/hyper_resource.rb', line 174 def inspect # :nodoc: "#<#{self.class}:0x#{"%x" % self.object_id} @root=#{self.root.inspect} "+ "@href=#{self.href.inspect} @loaded=#{self.loaded} "+ "@namespace=#{self.namespace.inspect} ...>" end |
#outgoing_body_filter(attr_hash) ⇒ Object
outgoing_body_filter filters a hash of attribute keys and values on their way from a HyperResource to a request body. Override this in a subclass of HyperResource to implement filters on outgoing data.
128 129 130 |
# File 'lib/hyper_resource.rb', line 128 def outgoing_body_filter(attr_hash) attr_hash end |
#outgoing_uri_filter(attr_hash) ⇒ Object
outgoing_uri_filter filters a hash of attribute keys and values on their way from a HyperResource to a URL. Override this in a subclass of HyperResource to implement filters on outgoing URI parameters.
136 137 138 |
# File 'lib/hyper_resource.rb', line 136 def outgoing_uri_filter(attr_hash) attr_hash end |
#response_body ⇒ Object
response_body is deprecated in favor of response_object.
181 |
# File 'lib/hyper_resource.rb', line 181 def response_body; response_object end |