class ActionDispatch::Journey::Formatter

def generate(name, options, path_parameters, parameterize = nil)

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