Class: ActionDispatch::Journey::Formatter

Inherits:
Object
  • Object
show all
Defined in:
lib/action_dispatch/journey/formatter.rb

Overview

The Formatter class is used for formatting URLs. For example, parameters passed to ‘url_for` in Rails will eventually call Formatter#generate.

Defined Under Namespace

Classes: MissingRoute, RouteWithParams

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(routes) ⇒ Formatter

Returns a new instance of Formatter.



15
16
17
18
# File 'lib/action_dispatch/journey/formatter.rb', line 15

def initialize(routes)
  @routes = routes
  @cache  = nil
end

Instance Attribute Details

#routesObject (readonly)

Returns the value of attribute routes.



13
14
15
# File 'lib/action_dispatch/journey/formatter.rb', line 13

def routes
  @routes
end

Instance Method Details

#clearObject



105
106
107
# File 'lib/action_dispatch/journey/formatter.rb', line 105

def clear
  @cache = nil
end

#eager_load!Object



109
110
111
112
# File 'lib/action_dispatch/journey/formatter.rb', line 109

def eager_load!
  cache
  nil
end

#generate(name, options, path_parameters) ⇒ Object



61
62
63
64
65
66
67
68
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
# File 'lib/action_dispatch/journey/formatter.rb', line 61

def generate(name, options, path_parameters)
  original_options = options.dup
  path_params = options.delete(:path_params) || {}
  options = path_params.merge(options)
  constraints = path_parameters.merge(options)
  missing_keys = nil

  match_route(name, constraints) do |route|
    parameterized_parts = extract_parameterized_parts(route, options, path_parameters)

    # Skip this route unless a name has been provided or it is a standard Rails
    # route since we can't determine whether an options hash passed to url_for
    # matches a Rack application or a redirect.
    next unless name || route.dispatcher?

    missing_keys = missing_keys(route, parameterized_parts)
    next if missing_keys && !missing_keys.empty?
    params = options.delete_if do |key, _|
      # top-level params' normal behavior of generating query_params should be
      # preserved even if the same key is also a bind_param
      parameterized_parts.key?(key) || route.defaults.key?(key) ||
        (path_params.key?(key) && !original_options.key?(key))
    end

    defaults       = route.defaults
    required_parts = route.required_parts

    route.parts.reverse_each do |key|
      break if defaults[key].nil? && parameterized_parts[key].present?
      next if parameterized_parts[key].to_s != defaults[key].to_s
      break if required_parts.include?(key)

      parameterized_parts.delete(key)
    end

    return RouteWithParams.new(route, parameterized_parts, params)
  end

  unmatched_keys = (missing_keys || []) & constraints.keys
  missing_keys = (missing_keys || []) - unmatched_keys

  MissingRoute.new(constraints, missing_keys, unmatched_keys, routes, name)
end