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 and caches 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
Creates and caches the URI by filling in the resource template’s URI template with params.
Methods inherited from Path
#delete, #get, #http_client, #inspect, #merge_http_options, #post, #put, #uri_template
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] metadata describing the web resource
33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/path-to/described_routes.rb', line 33 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")
111 112 113 114 115 116 117 118 119 120 |
# File 'lib/path-to/described_routes.rb', line 111 def method_missing(method, *args) child_resource_template = resource_template.find_by_rel(method.to_s).first 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.
21 22 23 |
# File 'lib/path-to/described_routes.rb', line 21 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.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/path-to/described_routes.rb', line 74 def [](*args) positional_params, params_hash = extract_params(args, params) known_keys = params_hash.keys child_resource_template = resource_template.find_by_rel(nil).detect do |t| (t.positional_params(resource_template)[positional_params.length..-1] - t.optional_params - known_keys).empty? 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 and caches the application in the parent hierarchy.
57 58 59 |
# File 'lib/path-to/described_routes.rb', line 57 def application @application ||= parent.application if parent end |
#child_class_for(instance, method, params, template) ⇒ Object
Delegated to the application
62 63 64 |
# File 'lib/path-to/described_routes.rb', line 62 def child_class_for(instance, method, params, template) application.child_class_for(instance, method, params, template) end |
#uri ⇒ Object
Creates and caches the URI by filling in the resource template’s URI template with params
50 51 52 |
# File 'lib/path-to/described_routes.rb', line 50 def uri @uri ||= resource_template.uri_for(params, application.base) end |