Class: ActionDispatch::Journey::Formatter
Do not use. This class is for internal use only.
| Relationships & Source Files | |
| Namespace Children | |
|
Classes:
| |
| Inherits: | Object |
| Defined in: | actionpack/lib/action_dispatch/journey/formatter.rb |
Overview
Class Method Summary
- .new(routes) ⇒ Formatter constructor
Instance Attribute Summary
- #routes readonly
Instance Method Summary
- #clear
- #eager_load!
- #freeze
- #generate(name, options, path_parameters)
- #build_cache private
- #cache private
- #extract_parameterized_parts(route, options, recall) private
- #match_route(name, options) private
-
#missing_keys(route, parts)
private
Returns an array populated with missing keys if any are present.
- #named_routes private
- #non_recursive(cache, options, dispatchers_only:) private
Constructor Details
.new(routes) ⇒ Formatter
Instance Attribute Details
#routes (readonly)
[ GitHub ]# File 'actionpack/lib/action_dispatch/journey/formatter.rb', line 11
attr_reader :routes
Instance Method Details
#build_cache (private)
[ GitHub ]# File 'actionpack/lib/action_dispatch/journey/formatter.rb', line 208
def build_cache root = { ___routes: [] } routes.routes.each_with_index do |route, i| leaf = route.required_defaults.inject(root) do |h, tuple| h[tuple] ||= {} end # Rack applications and redirects are only candidates when a route name is # given, since we can't determine whether an options hash passed to url_for # matches them. bucket = route.dispatcher? ? :___routes : :___non_dispatchers (leaf[bucket] ||= []) << [i, route] end root end
#cache (private)
[ GitHub ]# File 'actionpack/lib/action_dispatch/journey/formatter.rb', line 223
def cache @cache ||= build_cache end
#clear
[ GitHub ]# File 'actionpack/lib/action_dispatch/journey/formatter.rb', line 108
def clear @cache = nil end
#eager_load!
[ GitHub ]# File 'actionpack/lib/action_dispatch/journey/formatter.rb', line 112
def eager_load! cache nil end
#extract_parameterized_parts(route, options, recall) (private)
[ GitHub ]# File 'actionpack/lib/action_dispatch/journey/formatter.rb', line 124
def extract_parameterized_parts(route, , recall) parameterized_parts = recall.merge() # Keep the prefix through the last supplied part, plus all required parts. parts = route.parts last_kept = parts.rindex { |part| (.key?(part) || route..key?(part)) && !([part].nil? && recall[part].nil?) } || -1 keys_to_keep = parts.take(last_kept + 1) | route.required_parts parameterized_parts.delete_if do |bad_key, _| !keys_to_keep.include?(bad_key) end parameterized_parts.transform_values!(&:to_param) parameterized_parts.compact! parameterized_parts end
#freeze
[ GitHub ]# File 'actionpack/lib/action_dispatch/journey/formatter.rb', line 117
def freeze eager_load! super end
#generate(name, options, path_parameters)
[ GitHub ]# File 'actionpack/lib/action_dispatch/journey/formatter.rb', line 59
def generate(name, , path_parameters) path_params = .delete(:path_params) if path_params.is_a?(Hash) = = path_params.merge() else path_params = nil = .dup end constraints = path_parameters.merge() missing_keys = nil match_route(name, constraints) do |route| parameterized_parts = extract_parameterized_parts(route, , path_parameters) missing_keys = missing_keys(route, parameterized_parts) next if missing_keys && !missing_keys.empty? params = .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) && !.key?(key)) end defaults = route.defaults required_parts = route.required_parts # After query param extraction, so empty values are consumed as path parts. parameterized_parts.delete_if do |key, value| value.to_s.blank? && !required_parts.include?(key) end 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
#match_route(name, options) (private)
[ GitHub ]# File 'actionpack/lib/action_dispatch/journey/formatter.rb', line 148
def match_route(name, ) if named_routes.key?(name) yield named_routes[name] else routes = non_recursive(cache, , dispatchers_only: !name) supplied_keys = .each_with_object({}) do |(k, v), h| h[k.is_a?(Symbol) ? k.name : k.to_s] = true if v end hash = routes.group_by { |_, r| r.score(supplied_keys) } hash.keys.sort.reverse_each do |score| break if score < 0 hash[score].sort_by { |i, _| i }.each do |_, route| yield route end end end end
#missing_keys(route, parts) (private)
Returns an array populated with missing keys if any are present.
# File 'actionpack/lib/action_dispatch/journey/formatter.rb', line 188
def missing_keys(route, parts) missing_keys = nil tests = route.path.requirements_for_missing_keys_check route.required_parts.each { |key| case tests[key] when nil unless parts[key] missing_keys ||= [] missing_keys << key end else unless tests[key].match?(parts[key]) missing_keys ||= [] missing_keys << key end end } missing_keys end
#named_routes (private)
[ GitHub ]# File 'actionpack/lib/action_dispatch/journey/formatter.rb', line 144
def named_routes routes.named_routes end
#non_recursive(cache, options, dispatchers_only:) (private)
[ GitHub ]# File 'actionpack/lib/action_dispatch/journey/formatter.rb', line 170
def non_recursive(cache, , dispatchers_only:) routes = [] queue = [cache] while queue.any? c = queue.shift routes.concat(c[:___routes]) if c.key?(:___routes) routes.concat(c[:___non_dispatchers]) if !dispatchers_only && c.key?(:___non_dispatchers) .each do |pair| queue << c[pair] if c.key?(pair) end end routes end