module ActionDispatch::Routing::Mapper::Base
def app_name(app, rails_app)
def app_name(app, rails_app) if rails_app app.railtie_name elsif app.is_a?(Class) class_name = app.name ActiveSupport::Inflector.underscore(class_name).tr("/", "_") end end
def default_url_options=(options)
def default_url_options=(options) @set.default_url_options = options end
def define_generate_prefix(app, name)
def define_generate_prefix(app, name) _route = @set.named_routes.get name _routes = @set _url_helpers = @set.url_helpers script_namer = ->(options) do prefix_options = options.slice(*_route.segment_keys) prefix_options[:script_name] = "" if options[:original_script_name] if options[:_recall] prefix_options.reverse_merge!(options[:_recall].slice(*_route.segment_keys)) end # We must actually delete prefix segment keys to avoid passing them to next # url_for. _route.segment_keys.each { |k| options.delete(k) } _url_helpers.public_send("#{name}_path", prefix_options) end app.routes.define_mounted_helper(name, script_namer) app.routes.extend Module.new { def optimize_routes_generation?; false; end define_method :find_script_name do |options| if options.key?(:script_name) && options[:script_name].present? super(options) else script_namer.call(options) end end } end
def has_named_route?(name)
def has_named_route?(name) @set.named_routes.key?(name) end
def match(path, options = nil)
disable it by supplying `false`.
: Allows you to specify the default value for optional `format` segment or
:format
match 'path', to: 'c#a', anchor: false, via: :get
# Matches any request starting with 'path'
the pattern matches any request prefixed with the given path.
: Boolean to anchor a `match` pattern. Default is true. When set to false,
:anchor
See `Scoping#defaults` for its scope equivalent.
match 'path', to: 'c#a', defaults: { format: 'jpg' }, via: :get
# Sets params[:format] to 'jpg' by default
: Sets defaults for parameters
:defaults
See `Scoping#constraints` for more examples with its scope equivalent.
match 'path', to: 'c#a', constraints: PermitList.new, via: :get
end
def matches?(request) request.remote_ip == '1.2.3.4' end
class PermitList
match 'json_only', constraints: { format: 'json' }, via: :get
match 'path/:id', constraints: { id: /[A-Z]\d{5}/ }, via: :get
Range, etc.).
be specified with any object that responds to `===` (e.g. String, Array,
responds to `matches?`. In addition, constraints other than path can also
: Constrains parameters with a hash of regular expressions or an object that
:constraints
end
end
match 'foo', to: 'c#a', via: [:get, :post]
member do
resource :bar do
Is equivalent to:
end
match 'foo', to: 'c#a', on: :member, via: [:get, :post]
resource :bar do
block. For example:
are `:member`, `:collection`, and `:new`. Only use within `resource(s)`
: Shorthand for wrapping routes in a specific RESTful context. Valid values
:on
match 'path', to: RackApp, via: :get
match 'path', to: -> (env) { [200, {}, ["Success!"]] }, via: :get
match 'path', to: 'controller#action', via: :get
string representing a controller's action.
: Points to a `Rack` endpoint. Can be an object that responds to `call` or a
:to
match 'path', to: 'c#a', via: :all
match 'path', to: 'c#a', via: [:get, :post]
match 'path', to: 'c#a', via: :get
: Allowed HTTP verb(s) for route.
:via
: The name used to generate routing helpers.
:as
See `Scoping#namespace` for its scope equivalent.
# => Sekret::PostsController
match 'path', to: 'c#a', module: 'sekret', controller: 'posts', via: :get
: The namespace for :controller.
:module
: The path prefix for the routes.
:path
user_path(user) # => "/users/Phusion"
user = User.find_by(name: 'Phusion')
end
end
name
def to_param
class User < ActiveRecord::Base
construct a URL:
You can override `ActiveRecord::Base#to_param` of a related model to
DELETE /users/:name(.:format)
PATCH/PUT /users/:name(.:format)
GET /users/:name(.:format)
GET /users/:name/edit(.:format)
GET /users/new(.:format)
POST /users(.:format)
GET /users(.:format)
The `users` resource here will have the following routes generated for it:
resources :users, param: :name
your controller using `params[<:param>]`. In your router:
segment used to generate the routes). You can access that segment from
: Overrides the default resource identifier `:id` (name of the dynamic
:param
: The route's action.
:action
: The route's controller.
:controller
Any options not seen here are passed on as params with the URL.
### Options
one of the [HttpHelpers](rdoc-ref:HttpHelpers) instead `match`
implications, you must either specify the actions in the via options or use
Because requesting various HTTP verbs with a single action has security
match 'photos/:id', to: PhotosController.action(:show), via: :get
# Yes, controller actions are just rack endpoints
match 'photos/:id', to: PhotoRackApp, via: :get
match 'photos/:id', to: -> (hash) { [200, {}, ["Coming soon"]] }, via: :get
`call`:
A pattern can also point to a `Rack` endpoint i.e. anything that responds to
match 'photos/:id', controller: 'photos', action: 'show', via: :get
match 'photos/:id', to: 'photos#show', via: :get
`:controller` should be set in options or hash shorthand. Examples:
When a pattern points to an internal route, the route's `:action` and
variable name to attach the glob parameter to, the route can't be parsed.
To match a wildcard parameter, it must have a name assigned to it. Without a
# params[:title] = 'stairway-to-heaven'
# params[:category] = 'rock/classic'
# 'songs/rock/classic/stairway-to-heaven' sets
get 'songs/*category/:title', to: 'songs#show'
(globs) to params:
`:action` to the controller's action. A pattern can also map wildcard segments
Two of these symbols are special, `:controller` maps to the controller and
get ":controller/:action/:id"
Do:
match ":controller/:action/:id"
Instead of:
If you want to expose your action to GET, use `get` in the router:
parameters and thus available through `params` in an action.
Note that `:controller`, `:action`, and `:id` are interpreted as URL query
match ':controller/:action/:id', via: [:get, :post]
# sets :controller, :action, and :id in params
If you want to expose your action to both GET and POST, use:
HTTP method.
You should not use the `match` method in your router without specifying an
Matches a URL pattern to one or more routes.
def match(path, options = nil) end
def mount(app, options = nil)
This will generate the `exciting_path` and `exciting_url` helpers which can be
mount(SomeRackApp, at: "some_route", as: "exciting")
use the `:as` option:
`some_rack_app_path` or `some_rack_app_url`. To customize this helper's name,
named after the class specified, so for the above example the helper is either
All mounted applications come with routing helpers to access them. These are
For options, see `match`, as `mount` uses it internally.
mount SomeRackApp, at: "some_route"
Mount a Rack-based application to be used within the application.
def mount(app, options = nil) if options path = options.delete(:at) elsif Hash === app options = app app, path = options.find { |k, _| k.respond_to?(:call) } options.delete(app) if app end raise ArgumentError, "A rack application must be specified" unless app.respond_to?(:call) raise ArgumentError, <<~MSG unless path Must be called with mount point mount SomeRackApp, at: "some_route" or mount(SomeRackApp => "some_route") MSG rails_app = rails_app? app options[:as] ||= app_name(app, rails_app) target_as = name_for_action(options[:as], path) options[:via] ||= :all match(path, { to: app, anchor: false, format: false }.merge(options)) define_generate_prefix(app, target_as) if rails_app self end
def optimize_routes_generation?; false; end
def optimize_routes_generation?; false; end
def rails_app?(app)
def rails_app?(app) app.is_a?(Class) && app < Rails::Railtie end
def with_default_scope(scope, &block)
def with_default_scope(scope, &block) scope(scope) do instance_exec(&block) end end