Class: Jets::Router::Helpers::NamedRoutes::Proxy

Inherits:
Object
  • Object
show all
Includes:
AddFullUrl
Defined in:
lib/jets/router/helpers/named_routes/proxy.rb

Instance Method Summary collapse

Methods included from AddFullUrl

#add_full_url

Constructor Details

#initialize(view_context, helpers_module) ⇒ Proxy

Returns a new instance of Proxy.



5
6
7
# File 'lib/jets/router/helpers/named_routes/proxy.rb', line 5

def initialize(view_context, helpers_module)
  @helpers = helpers_class(helpers_module).new(view_context)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args) ⇒ Object

No need to check respond_to? and call raise NoMethodError again because anonymous class will already return a undefined method error.

It’s annoying that we need to add_full_url here because the proxy calls the url methods with a module view_context instead of the controller or view_context instance. So we don’t have access to the request and url_options. The url_options are only available in the controller or view_context instance.

So we call the path method instead and then add_full_url here. Not calling the url method directly because could add the full url twice, when the user is setting the default_url_options. Also calling the url method would cause an error because request and url_options is not available.

The logic is a bit convoluted but it works. Rails does something similar with their RoutesProxy class and view_context.url_options.



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/jets/router/helpers/named_routes/proxy.rb', line 52

def method_missing(method_name, *args)
  path_name = method_name.to_s.sub(/_url$/, '_path').to_sym
  path = @helpers.send(path_name, *args)
  if method_name.to_s.end_with?('_url')
    options = args.extract_options!
    options.merge!(path: path)
    options = url_options.merge(options)
    add_full_url(options)
  else
    path
  end
end

Instance Method Details

#helpers_class(helpers_module) ⇒ Object

  • The helpers_module is passed as a argument to give the anonymous class access via closure at include time.

  • view_context is passed at initialize to provide access at instantiation time.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/jets/router/helpers/named_routes/proxy.rb', line 12

def helpers_class(helpers_module)
  Class.new do
    include helpers_module # IE: Generated::MainAppHelpers
    def initialize(view_context)
      @view_context = view_context
    end

    # Important:
    #
    # * The add_full_url method needs url_options.
    #   Without url_options the proxy methods are unavailable and creates
    #   an infinite loop with method_missing.
    # * request is needed for add_apigw_stage? to check request correctly
    #   Otherwise, gems like kingsman, that use the named routes proxy methods,
    #   won't get able to get the correct url with the stage name prepended.
    #
    # The request is the main reason an anonymous class is used since the
    # view_context has included modules like ApigwStage that assume a
    # request method is available.
    delegate :url_options, :request, :event, to: :@view_context
  end
end