Define custom URL helpers that will be added to the application's routes. This allows you to override and/or replace the default behavior of routing helpers, e.g:
direct :homepage do
"http://www.rubyonrails.org"
end
direct :commentable do |model|
[ model, anchor: model.dom_id ]
end
direct :main do
{ controller: "pages", action: "index", subdomain: "www" }
end
The return value from the block passed to direct must be a
valid set of arguments for url_for which will actually build
the URL string. This can be one of the following:
-
A string, which is treated as a generated URL
-
A hash, e.g.
{ controller: "pages", action: "index" } -
An array, which is passed to
polymorphic_url -
An Active Model instance
-
An Active Model class
NOTE: Other URL helpers can be called in the block but be careful not to invoke your custom URL helper again otherwise it will result in a stack overflow error.
You can also specify default options that will be passed through to your URL helper definition, e.g:
direct :browse, page: 1, size: 10 do |options|
[ :products, options.merge(params.permit(:page, :size).to_h.symbolize_keys) ]
end
In this instance the params object comes from the context in
which the block is executed, e.g. generating a URL inside a controller
action or a view. If the block is executed where there isn't a
params object such as this:
Rails.application.routes.url_helpers.browse_path
then it will raise a NameError. Because of this you need to be
aware of the context in which you will use your custom URL helper when
defining it.
NOTE: The direct method can't be used inside of a scope
block such as namespace or scope and will raise
an error if it detects that it is.
Define custom polymorphic mappings of models to URLs. This alters the
behavior of polymorphic_url and consequently the behavior of
link_to and form_for when passed a model
instance, e.g:
resource :basket
resolve "Basket" do
[:basket]
end
This will now generate “/basket” when a Basket instance is
passed to link_to or form_for instead of the
standard “/baskets/:id”.
NOTE: This custom behavior only applies to simple polymorphic URLs where a single model instance is passed and not more complicated forms, e.g:
# config/routes.rb
resource :profile
namespace :admin do
resources :users
end
resolve("User") { [:profile] }
# app/views/application/_menu.html.erb
link_to "Profile", @current_user
link_to "Profile", [:admin, @current_user]
The first link_to will generate “/profile” but the second will
generate the standard polymorphic URL of “/admin/users/1”.
You can pass options to a polymorphic mapping - the arity for the block needs to be two as the instance is passed as the first argument, e.g:
resolve "Basket", anchor: "items" do |basket, options|
[:basket, options]
end
This generates the URL “/basket#items” because when the last item in an
array passed to polymorphic_url is a hash then it's
treated as options to the URL helper that gets called.
NOTE: The resolve method can't be used inside of a scope
block such as namespace or scope and will raise
an error if it detects that it is.
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 2149 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