Class: PathTo::DescribedRoutes::TemplatedPath
- Inherits:
-
Path
- Object
- WithParams
- Path
- PathTo::DescribedRoutes::TemplatedPath
- Defined in:
- lib/path-to/described_routes.rb
Overview
Implements PathTo::Path, represents a resource described by a ResourceTemplate
Instance Attribute Summary collapse
-
#resource_template ⇒ Object
readonly
Returns the value of attribute resource_template.
Attributes inherited from WithParams
Instance Method Summary collapse
-
#[](*args) ⇒ Object
Creates a child instance with new params, potentially finding a nested resource template that takes the additional params.
-
#application ⇒ Object
Finds (once) the application in the parent hierarchy.
-
#child_class_for(instance, method, params, template) ⇒ Object
Delegated to the application.
-
#initialize(parent, service, params, resource_template) ⇒ TemplatedPath
constructor
Initialize a TemplatedPath.
-
#method_missing(method, *args) ⇒ Object
Tries to respond to a missing method.
-
#uri ⇒ Object
Create and cache the URI by filling in the URI template with params.
-
#uri_template ⇒ Object
Get and cache the uri template from the resource tamplte.
Methods inherited from Path
#delete, #get, #http_client, #inspect, #merge_http_options, #post, #put
Methods inherited from WithParams
#child, #complete_params_hash!, #extract_params, #respond_to?
Constructor Details
#initialize(parent, service, params, resource_template) ⇒ TemplatedPath
Initialize a TemplatedPath. Raises ArgumentError if params doesn’t include all mandatory params expected by the resource template.
Parameters:
[parent] parent object path or application
[service] unused - resource_template.name is passed to super() instead. TODO: refactor
[params] hash of params; will be merged with the parent's params and passed when required to the resource template's URI template
[resource_template] describing the web resource
25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/path-to/described_routes.rb', line 25 def initialize(parent, service, params, resource_template) super(parent, resource_template.name, params) @resource_template = resource_template missing_params = resource_template.params - params.keys unless missing_params.empty? raise ArgumentError.new( "Missing params #{missing_params.join(', ')} " + "(template #{resource_template.name.inspect}," + " path_template #{resource_template.path_template.inspect}," + " params #{params.inspect})") end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object
Tries to respond to a missing method. We can do so if
-
we can find a resource template with rel matching the method name (direct children only)
-
#child_class_for returns a class or other factory object capable of creating a new child instance
Otherwise we invoke super in the hope of avoiding any hard-to-debug behaviour!
May take a combination of positional and named parameters, e.g.
users("dojo", "format" => "json")
114 115 116 117 118 119 120 121 122 123 |
# File 'lib/path-to/described_routes.rb', line 114 def method_missing(method, *args) child_resource_template = resource_template.resource_templates.detect{|t| t.rel == method.to_s} if child_resource_template && (child_class = child_class_for(self, method, params, child_resource_template)) positional_params, params_hash = extract_params(args, params) complete_params_hash!(params_hash, child_resource_template.positional_params(resource_template), positional_params) child(child_class, method, params_hash, child_resource_template) else super end end |
Instance Attribute Details
#resource_template ⇒ Object (readonly)
Returns the value of attribute resource_template.
13 14 15 |
# File 'lib/path-to/described_routes.rb', line 13 def resource_template @resource_template end |
Instance Method Details
#[](*args) ⇒ Object
Creates a child instance with new params, potentially finding a nested resource template that takes the additional params. May take a combination of positional and named parameters, e.g.
users["dojo", {"format" => "json"}]
Positional parameters are unsupported however if a new child template is not identified.
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 |
# File 'lib/path-to/described_routes.rb', line 75 def [](*args) positional_params, params_hash = extract_params(args, params) known_keys = params_hash.keys child_resource_template = resource_template.resource_templates.detect do |t| if t.rel.nil? (t.positional_params(resource_template)[positional_params.length..-1] - t.optional_params - known_keys).empty? end end if child_resource_template # we have a new child resource template; apply any positional params to the hash complete_params_hash!(params_hash, child_resource_template.positional_params(resource_template), positional_params) else # we're just adding optional params, no new template identified unless positional_params.empty? raise ArgumentError.new( "No matching child template; only named parameters can be used here. " + "positional_params=#{positional_params.inspect}, params_hash=#{params_hash.inspect}") end child_resource_template = resource_template end child_class = child_class_for(self, nil, params_hash, child_resource_template) child(child_class, nil, params_hash, child_resource_template) end |
#application ⇒ Object
Finds (once) the application in the parent hierarchy.
58 59 60 |
# File 'lib/path-to/described_routes.rb', line 58 def application @application ||= parent.application if parent end |
#child_class_for(instance, method, params, template) ⇒ Object
Delegated to the application
63 64 65 |
# File 'lib/path-to/described_routes.rb', line 63 def child_class_for(instance, method, params, template) application.child_class_for(instance, method, params, template) end |
#uri ⇒ Object
Create and cache the URI by filling in the URI template with params
49 50 51 52 53 |
# File 'lib/path-to/described_routes.rb', line 49 def uri @uri ||= begin Addressable::Template.new(uri_template).(params).to_s end end |
#uri_template ⇒ Object
Get and cache the uri template from the resource tamplte
42 43 44 |
# File 'lib/path-to/described_routes.rb', line 42 def uri_template @uri_template ||= resource_template.uri_template || (application.base + resource_template.path_template) end |