Class: PathTo::DescribedRoutes::TemplatedPath

Inherits:
Path show all
Defined in:
lib/path-to/described_routes.rb

Instance Attribute Summary collapse

Attributes inherited from WithParams

#params, #parent, #service

Instance Method Summary collapse

Methods inherited from Path

#delete, #get, #http_client, #inspect, #post, #put

Methods inherited from WithParams

#child, #respond_to?

Constructor Details

#initialize(parent, service, params, resource_template) ⇒ TemplatedPath

Returns a new instance of TemplatedPath.



9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/path-to/described_routes.rb', line 9

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

  1. we can find a resource template with rel matching the method name (direct children only)

  2. #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!



65
66
67
68
69
70
71
72
73
# File 'lib/path-to/described_routes.rb', line 65

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))
    params = args.inject(Hash.new){|h, arg| h.merge(arg)}
    child(child_class, method, params, child_resource_template)
  else
    super
  end
end

Instance Attribute Details

#resource_templateObject (readonly)

Returns the value of attribute resource_template.



7
8
9
# File 'lib/path-to/described_routes.rb', line 7

def resource_template
  @resource_template
end

Instance Method Details

#[](params = {}) ⇒ Object

Creates a child instance with new params, potentially finding a nested resource template that takes the additional params



48
49
50
51
52
53
54
55
# File 'lib/path-to/described_routes.rb', line 48

def [](params = {})
  keys = self.params.merge(params).keys
  child_resource_template = resource_template.resource_templates.detect{ |t|
    t.rel.nil? && (t.params - keys).empty?
  } || resource_template
  child_class = child_class_for(self, nil, params, child_resource_template)
  child(child_class, nil, params, child_resource_template)
end

#applicationObject

Finds (once) the application in the parent hierarchy.



36
37
38
# File 'lib/path-to/described_routes.rb', line 36

def application
  @application ||= parent.application if parent
end

#child_class_for(instance, method, params, template) ⇒ Object

Delegated to the application



41
42
43
# File 'lib/path-to/described_routes.rb', line 41

def child_class_for(instance, method, params, template)
  application.child_class_for(instance, method, params, template)
end

#uriObject



27
28
29
30
31
# File 'lib/path-to/described_routes.rb', line 27

def uri
  @uri ||= begin
    Addressable::Template.new(uri_template).expand(params).to_s
  end
end

#uri_templateObject



23
24
25
# File 'lib/path-to/described_routes.rb', line 23

def uri_template
  @uri_template ||= resource_template.uri_template || (application.base + resource_template.path_template)
end