Class: ActionDispatch::Routing::RouteSet
Relationships & Source Files | |
Namespace Children | |
Modules:
| |
Classes:
| |
Extension / Inclusion / Inheritance Descendants | |
Subclasses:
|
|
Inherits: | Object |
Defined in: | actionpack/lib/action_dispatch/routing/route_set.rb |
Overview
The RouteSet contains a collection of Route instances, representing the routes typically defined in config/routes.rb
.
Constant Summary
-
DEFAULT_CONFIG =
Internal use only
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 386Config.new(nil, false, nil)
-
PATH =
Internal use only
strategy for building URLs to send to the client
->( ) { ActionDispatch::Http::URL.path_for( ) }
-
RESERVED_OPTIONS =
Internal use only
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 840[:host, :protocol, :port, :subdomain, :domain, :tld_length, :trailing_slash, :anchor, :params, :only_path, :script_name, :original_script_name]
-
UNKNOWN =
Internal use only
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 352->( ) { ActionDispatch::Http::URL.url_for( ) }
Class Method Summary
- .default_resources_path_names Internal use only
- .new(config = DEFAULT_CONFIG.dup) ⇒ RouteSet constructor Internal use only
- .new_with_config(config) Internal use only
Instance Attribute Summary
- #api_only? ⇒ Boolean readonly Internal use only
- #default_scope rw Internal use only
- #default_scope=(new_default_scope) rw Internal use only
- #default_url_options rw Internal use only
- #disable_clear_and_finalize rw Internal use only
- #draw_paths rw Internal use only
- #empty? ⇒ Boolean readonly Internal use only
- #env_key readonly Internal use only
- #formatter rw Internal use only
- #named_routes rw Internal use only
- #optimize_routes_generation? ⇒ Boolean readonly Internal use only
- #polymorphic_mappings readonly Internal use only
- #resources_path_names rw Internal use only
- #router rw Internal use only
-
#routes
readonly
Internal use only
Alias for #set.
- #set (also: #routes) rw Internal use only
Instance Method Summary
-
#from_requirements(requirements)
Returns a Route matching the given requirements, or
nil
if none are found. - #add_polymorphic_mapping(klass, options, &block) Internal use only
- #add_route(mapping, name) Internal use only
- #add_url_helper(name, options, &block) Internal use only
- #append(&block) Internal use only
- #call(env) Internal use only
- #clear! Internal use only
- #default_env Internal use only
- #define_mounted_helper(name, script_namer = nil) Internal use only
- #draw(&block) Internal use only
- #eager_load! Internal use only
-
#extra_keys(options, recall = {})
Internal use only
Generate the path indicated by the arguments, and return an array of the keys that were not used to generate it.
- #finalize! Internal use only
- #find_script_name(options) Internal use only
- #generate_extras(options, recall = {}) Internal use only
- #generate_url_helpers(supports_path) Internal use only
-
#inspect
Internal use only
Since the router holds references to many parts of the system like engines, controllers and the application itself, inspecting the route set can actually be really slow, therefore we default alias inspect to to_s.
-
#mounted_helpers
Internal use only
Contains all the mounted helpers across different engines and the
main_app
helper for the application. - #path_for(options, route_name = nil, reserved = RESERVED_OPTIONS) Internal use only
- #prepend(&block) Internal use only
- #recognize_path(path, environment = {}) Internal use only
- #recognize_path_with_request(req, path, extras, raise_on_missing: true) Internal use only
- #relative_url_root Internal use only
- #request_class Internal use only
-
#url_for(options, route_name = nil, url_strategy = UNKNOWN, method_name = nil, reserved = RESERVED_OPTIONS)
Internal use only
The
options
argument must be a hash whose keys are symbols. - #url_helpers(supports_path = true) Internal use only
- #eval_block(block) private Internal use only
- #generate(route_name, options, recall = {}, method_name = nil) private Internal use only
- #make_request(env) private Internal use only
Constructor Details
.new(config = DEFAULT_CONFIG.dup) ⇒ RouteSet
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 388
def initialize(config = DEFAULT_CONFIG.dup) self.named_routes = NamedRouteCollection.new self.resources_path_names = self.class.default_resources_path_names self. = {} self.draw_paths = [] @config = config @append = [] @prepend = [] @disable_clear_and_finalize = false @finalized = false @env_key = "ROUTES_#{object_id}_SCRIPT_NAME" @default_env = nil @set = Journey::Routes.new @router = Journey::Router.new @set @formatter = Journey::Formatter.new self @polymorphic_mappings = {} end
Class Method Details
.default_resources_path_names
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 361
def self.default_resources_path_names { new: "new", edit: "edit" } end
.new_with_config(config)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 365
def self.new_with_config(config) route_set_config = DEFAULT_CONFIG.dup # engines apparently don't have this set if config.respond_to? :relative_url_root route_set_config.relative_url_root = config.relative_url_root end if config.respond_to? :api_only route_set_config.api_only = config.api_only end if config.respond_to? :default_scope route_set_config.default_scope = config.default_scope end new route_set_config end
Instance Attribute Details
#api_only? ⇒ Boolean
(readonly)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 419
def api_only? @config.api_only end
#default_scope (rw)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 423
def default_scope @config.default_scope end
#default_scope=(new_default_scope) (rw)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 427
def default_scope=(new_default_scope) @config.default_scope = new_default_scope end
#default_url_options (rw)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 356
attr_accessor :, :draw_paths
#disable_clear_and_finalize (rw)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 355
attr_accessor :disable_clear_and_finalize, :resources_path_names
#draw_paths (rw)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 356
attr_accessor :, :draw_paths
#empty? ⇒ Boolean
(readonly)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 641
def empty? routes.empty? end
#env_key (readonly)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 357
attr_reader :env_key, :polymorphic_mappings
#formatter (rw)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 354
attr_accessor :formatter, :set, :named_routes, :router
#named_routes (rw)
#optimize_routes_generation? ⇒ Boolean
(readonly)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 844
def optimize_routes_generation? .empty? end
#polymorphic_mappings (readonly)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 357
attr_reader :env_key, :polymorphic_mappings
#resources_path_names (rw)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 355
attr_accessor :disable_clear_and_finalize, :resources_path_names
#router (rw)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 354
attr_accessor :formatter, :set, :named_routes, :router
#routes (readonly)
Alias for #set.
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 359
alias :routes :set
#set (rw) Also known as: #routes
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 354
attr_accessor :formatter, :set, :named_routes, :router
Instance Method Details
#add_polymorphic_mapping(klass, options, &block)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 676
def add_polymorphic_mapping(klass, , &block) @polymorphic_mappings[klass] = CustomUrlHelper.new(klass, , &block) end
#add_route(mapping, name)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 645
def add_route(mapping, name) raise ArgumentError, "Invalid route name: '#{name}'" unless name.blank? || name.to_s.match(/^[_a-z]\w*$/i) if name && named_routes[name] raise ArgumentError, "Invalid route name, already in use: '#{name}' \n" \ "You may have defined two routes with the same name using the `:as` option, or " \ "you may be overriding a route already defined by a resource with the same naming. " \ "For the latter, you can restrict the routes created with `resources` as explained here: \n" \ "https://guides.rubyonrails.org/routing.html#restricting-the-routes-created" end route = @set.add_route(name, mapping) named_routes[name] = route if name if route.segment_keys.include?(:controller) ActionDispatch.deprecator.warn(<<-MSG.squish) Using a dynamic :controller segment in a route is deprecated and will be removed in Rails 8.1. MSG end if route.segment_keys.include?(:action) ActionDispatch.deprecator.warn(<<-MSG.squish) Using a dynamic :action segment in a route is deprecated and will be removed in Rails 8.1. MSG end route end
#add_url_helper(name, options, &block)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 680
def add_url_helper(name, , &block) named_routes.add_url_helper(name, , &block) end
#append(&block)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 466
def append(&block) @append << block end
#call(env)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 905
def call(env) req = make_request(env) req.path_info = Journey::Router::Utils.normalize_path(req.path_info) @router.serve(req) end
#clear!
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 490
def clear! @finalized = false named_routes.clear set.clear formatter.clear @polymorphic_mappings.clear @prepend.each { |blk| eval_block(blk) } end
#default_env
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 440
def default_env if != @default_env&.[]("action_dispatch.routes.default_url_options") = .dup.freeze uri = URI(ActionDispatch::Http::URL.full_url_for(host: "example.org", ** )) @default_env = { "action_dispatch.routes" => self, "action_dispatch.routes.default_url_options" => , "HTTPS" => uri.scheme == "https" ? "on" : "off", "rack.url_scheme" => uri.scheme, "HTTP_HOST" => uri.port == uri.default_port ? uri.host : "#{uri.host}:#{uri.port}", "SCRIPT_NAME" => uri.path.chomp("/"), "rack.input" => "", }.freeze end @default_env end
#define_mounted_helper(name, script_namer = nil)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 511
def define_mounted_helper(name, script_namer = nil) return if MountedHelpers.method_defined?(name) routes = self helpers = routes.url_helpers MountedHelpers.class_eval do define_method "_#{name}" do RoutesProxy.new(routes, _routes_context, helpers, script_namer) end end MountedHelpers.class_eval(<<-RUBY, __FILE__, __LINE__ + 1) def #{name} @_#{name} ||= _#{name} end RUBY end
#draw(&block)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 459
def draw(&block) clear! unless @disable_clear_and_finalize eval_block(block) finalize! unless @disable_clear_and_finalize nil end
#eager_load!
#eval_block(block) (private)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 474
def eval_block(block) mapper = Mapper.new(self) if default_scope mapper.with_default_scope(default_scope, &block) else mapper.instance_exec(&block) end end
#extra_keys(options, recall = {})
Generate the path indicated by the arguments, and return an array of the keys that were not used to generate it.
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 820
def extra_keys(, recall = {}) generate_extras(, recall).last end
#finalize!
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 484
def finalize! return if @finalized @append.each { |blk| eval_block(blk) } @finalized = true end
#find_script_name(options)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 848
def find_script_name( ) .delete(:script_name) || relative_url_root || "" end
#from_requirements(requirements)
Returns a Route matching the given requirements, or nil
if none are found.
This is intended for use by tools such as Language Servers.
Given the routes are defined as:
resources :posts
Then the following will return the Route for the show
action:
Rails.application.routes.from_requirements(controller: "posts", action: "show")
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 29
def from_requirements(requirements) routes.find { |route| route.requirements == requirements } end
#generate(route_name, options, recall = {}, method_name = nil) (private)
#generate_extras(options, recall = {})
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 824
def generate_extras(, recall = {}) if recall = .merge(_recall: recall) end route_name = .delete :use_route generator = generate(route_name, , recall) path_info = path_for(, route_name, []) [URI(path_info).path, generator.params.except(:_recall).keys] end
#generate_url_helpers(supports_path)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 538
def generate_url_helpers(supports_path) routes = self Module.new do extend ActiveSupport::Concern include UrlFor # Define url_for in the singleton level so one can do: # Rails.application.routes.url_helpers.url_for(args) proxy_class = Class.new do include UrlFor include routes.named_routes.path_helpers_module include routes.named_routes.url_helpers_module attr_reader :_routes def initialize(routes) @_routes = routes end def optimize_routes_generation? @_routes.optimize_routes_generation? end end @_proxy = proxy_class.new(routes) class << self def url_for( ) @_proxy.url_for( ) end def full_url_for( ) @_proxy.full_url_for( ) end def route_for(name, *args) @_proxy.route_for(name, *args) end def optimize_routes_generation? @_proxy.optimize_routes_generation? end def polymorphic_url(record_or_hash_or_array, = {}) @_proxy.polymorphic_url(record_or_hash_or_array, ) end def polymorphic_path(record_or_hash_or_array, = {}) @_proxy.polymorphic_path(record_or_hash_or_array, ) end def _routes; @_proxy._routes; end def ; {}; end end url_helpers = routes.named_routes.url_helpers_module # Make named_routes available in the module singleton as well, so one can do: # Rails.application.routes.url_helpers.posts_path extend url_helpers # Any class that includes this module will get all named routes... include url_helpers if supports_path path_helpers = routes.named_routes.path_helpers_module include path_helpers extend path_helpers end # plus a singleton class method called _routes ... included do redefine_singleton_method(:_routes) { routes } end # And an instance method _routes. Note that UrlFor (included in this module) add # extra conveniences for working with @_routes. define_method(:_routes) { @_routes || routes } define_method(:_generate_paths_by_default) do supports_path end private :_generate_paths_by_default # If the module is included more than once (for example, in a subclass of an # ancestor that includes the module), ensure that the `_routes` singleton and # instance methods return the desired route set by including a new copy of the # module (recursively if necessary). Note that this method is called for each # inclusion, whereas the above `included` block is run only for the initial # inclusion of each copy. def self.included(base) super if base.respond_to?(:_routes) && !base._routes.equal?(@_proxy._routes) @dup_for_reinclude ||= self.dup base.include @dup_for_reinclude end end end end
#inspect
Since the router holds references to many parts of the system like engines, controllers and the application itself, inspecting the route set can actually be really slow, therefore we default alias inspect to to_s.
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 37
alias inspect to_s
#make_request(env) (private)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 435
def make_request(env) request_class.new env end
#mounted_helpers
Contains all the mounted helpers across different engines and the main_app
helper for the application. You can include this in your classes if you want to access routes for other engines.
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 507
def mounted_helpers MountedHelpers end
#path_for(options, route_name = nil, reserved = RESERVED_OPTIONS)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 852
def path_for(, route_name = nil, reserved = RESERVED_OPTIONS) url_for(, route_name, PATH, nil, reserved) end
#prepend(&block)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 470
def prepend(&block) @prepend << block end
#recognize_path(path, environment = {})
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 911
def recognize_path(path, environment = {}) method = (environment[:method] || "GET").to_s.upcase path = Journey::Router::Utils.normalize_path(path) unless path&.include?("://") extras = environment[:extras] || {} begin env = Rack::MockRequest.env_for(path, method: method) rescue URI::InvalidURIError => e raise ActionController::RoutingError, e. end req = make_request(env) recognize_path_with_request(req, path, extras) end
#recognize_path_with_request(req, path, extras, raise_on_missing: true)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 926
def recognize_path_with_request(req, path, extras, raise_on_missing: true) @router.recognize(req) do |route, params| params.merge!(extras) params.each do |key, value| if value.is_a?(String) value = value.dup.force_encoding(Encoding::BINARY) params[key] = URI::RFC2396_PARSER.unescape(value) end end req.path_parameters = params app = route.app if app.matches?(req) && app.dispatcher? begin req.controller_class rescue NameError raise ActionController::RoutingError, "A route matches #{path.inspect}, but references missing controller: #{params[:controller].camelize}Controller" end return req.path_parameters elsif app.matches?(req) && app.engine? path_parameters = app.rack_app.routes.recognize_path_with_request(req, path, extras, raise_on_missing: false) return path_parameters if path_parameters end end if raise_on_missing raise ActionController::RoutingError, "No route matches #{path.inspect}" end end
#relative_url_root
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 415
def relative_url_root @config.relative_url_root end
#request_class
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 431
def request_class ActionDispatch::Request end
#url_for(options, route_name = nil, url_strategy = UNKNOWN, method_name = nil, reserved = RESERVED_OPTIONS)
The options
argument must be a hash whose keys are symbols.
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 857
def url_for(, route_name = nil, url_strategy = UNKNOWN, method_name = nil, reserved = RESERVED_OPTIONS) = .merge user = password = nil if [:user] && [:password] user = .delete :user password = .delete :password end recall = .delete(:_recall) { {} } original_script_name = .delete(:original_script_name) script_name = find_script_name if original_script_name script_name = original_script_name + script_name end = .dup reserved.each { |ro| .delete ro } route_with_params = generate(route_name, , recall) path = route_with_params.path(method_name) if [:trailing_slash] && ! [:format] && !path.end_with?("/") path += "/" end params = route_with_params.params if .key? :params if [:params].respond_to?(:to_hash) params.merge! [:params] else params[:params] = [:params] end end [:path] = path [:script_name] = script_name [:params] = params [:user] = user [:password] = password url_strategy.call end
#url_helpers(supports_path = true)
# File 'actionpack/lib/action_dispatch/routing/route_set.rb', line 530
def url_helpers(supports_path = true) if supports_path @url_helpers_with_paths ||= generate_url_helpers(true) else @url_helpers_without_paths ||= generate_url_helpers(false) end end