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

Modules: RegexCaseComparator

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(routes) ⇒ Formatter

Returns a new instance of Formatter.

[View source]

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

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

Instance Attribute Details

#routesObject (readonly)

Returns the value of attribute routes.


11
12
13
# File 'lib/action_dispatch/journey/formatter.rb', line 11

def routes
  @routes
end

Instance Method Details

#clearObject

[View source]

60
61
62
# File 'lib/action_dispatch/journey/formatter.rb', line 60

def clear
  @cache = nil
end

#generate(name, options, path_parameters, parameterize = nil) ⇒ Object

[View source]

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/action_dispatch/journey/formatter.rb', line 18

def generate(name, options, path_parameters, parameterize = nil)
  constraints = path_parameters.merge(options)
  missing_keys = nil

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

    # 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.dup.delete_if do |key, _|
      parameterized_parts.key?(key) || route.defaults.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 [route.format(parameterized_parts), params]
  end

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

  message = "No route matches #{Hash[constraints.sort_by { |k, v| k.to_s }].inspect}".dup
  message << ", missing required keys: #{missing_keys.sort.inspect}" if missing_keys && !missing_keys.empty?
  message << ", possible unmatched constraints: #{unmatched_keys.sort.inspect}" if unmatched_keys && !unmatched_keys.empty?

  raise ActionController::UrlGenerationError, message
end