module ActionDispatch::Routing::Mapper::CustomUrls

def direct(name, options = {}, &block)

`namespace` or `scope` and will raise an error if it detects that it is.
NOTE: The `direct` method can't be used inside of a scope block such as

context in which you will use your custom URL helper when defining it.
then it will raise a `NameError`. Because of this you need to be aware of the

Rails.application.routes.url_helpers.browse_path

the block is executed where there isn't a `params` object such as this:
is executed, e.g. generating a URL inside a controller action or a view. If
In this instance the `params` object comes from the context in which the block

end
[ :products, options.merge(params.permit(:page, :size).to_h.symbolize_keys) ]
direct :browse, page: 1, size: 10 do |options|

helper definition, e.g:
You can also specify default options that will be passed through to your URL

overflow error.
invoke your custom URL helper again otherwise it will result in a stack
NOTE: Other URL helpers can be called in the block but be careful not to


* An Active Model class
* An Active Model instance
* An array, which is passed to `polymorphic_url`
* A hash, e.g. `{ controller: "pages", action: "index" }`
* A string, which is treated as a generated URL

one of the following:
arguments for `url_for` which will actually build the URL string. This can be
The return value from the block passed to `direct` must be a valid set of

end
{ controller: "pages", action: "index", subdomain: "www" }
direct :main do

end
[ model, anchor: model.dom_id ]
direct :commentable do |model|

end
"https://rubyonrails.org"
direct :homepage do

e.g:
allows you to override and/or replace the default behavior of routing helpers,
Define custom URL helpers that will be added to the application's routes. This
def direct(name, options = {}, &block)
  unless @scope.root?
    raise RuntimeError, "The direct method can't be used inside a routes scope block"
  end
  @set.add_url_helper(name, options, &block)
end

def resolve(*args, &block)

`namespace` or `scope` and will raise an error if it detects that it is.
NOTE: The `resolve` method can't be used inside of a scope block such as

helper that gets called.
passed to `polymorphic_url` is a hash then it's treated as options to the URL
This generates the URL "/basket#items" because when the last item in an array

end
[:basket, options]
resolve "Basket", anchor: "items" do |basket, options|

to be two as the instance is passed as the first argument, e.g:
You can pass options to a polymorphic mapping - the arity for the block needs

standard polymorphic URL of "/admin/users/1".
The first `link_to` will generate "/profile" but the second will generate the

link_to "Profile", [:admin, @current_user]
link_to "Profile", @current_user
# app/views/application/_menu.html.erb

resolve("User") { [:profile] }

end
resources :users
namespace :admin do
resource :profile
# config/routes.rb

single model instance is passed and not more complicated forms, e.g:
NOTE: This custom behavior only applies to simple polymorphic URLs where a

`link_to` or `form_for` instead of the standard "/baskets/:id".
This will now generate "/basket" when a `Basket` instance is passed to

end
[:basket]
resolve "Basket" do

resource :basket

when passed a model instance, e.g:
of `polymorphic_url` and consequently the behavior of `link_to` and `form_for`
Define custom polymorphic mappings of models to URLs. This alters the behavior
def resolve(*args, &block)
  unless @scope.root?
    raise RuntimeError, "The resolve method can't be used inside a routes scope block"
  end
  options = args.extract_options!
  args = args.flatten(1)
  args.each do |klass|
    @set.add_polymorphic_mapping(klass, options, &block)
  end
end