Module: ActionDispatch::Routing::Mapper::CustomUrls
- Included in:
- ActionDispatch::Routing::Mapper
- Defined in:
- lib/action_dispatch/routing/mapper.rb
Instance Method Summary collapse
-
#direct(name, options = {}, &block) ⇒ Object
Define custom url helpers that will be added to the application’s routes.
-
#resolve(*args, &block) ⇒ Object
Define custom polymorphic mappings of models to urls.
Instance Method Details
#direct(name, options = {}, &block) ⇒ Object
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 ||
[ :products, .merge(params.permit(:page, :size).to_h.symbolize_keys) ]
end
In this instance the ‘params` object comes from the context in which the 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.
2085 2086 2087 2088 2089 2090 2091 |
# File 'lib/action_dispatch/routing/mapper.rb', line 2085 def direct(name, = {}, &block) unless @scope.root? raise RuntimeError, "The direct method can't be used inside a routes scope block" end @set.add_url_helper(name, , &block) end |
#resolve(*args, &block) ⇒ Object
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, |
[:basket, ]
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.
2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 |
# File 'lib/action_dispatch/routing/mapper.rb', line 2137 def resolve(*args, &block) unless @scope.root? raise RuntimeError, "The resolve method can't be used inside a routes scope block" end = args. args = args.flatten(1) args.each do |klass| @set.add_polymorphic_mapping(klass, , &block) end end |