Reputation: 3011
Is there some way to provide a default value to the url/path helpers?
I have an optional scope wrapping around all of my routes:
#config/routes.rb
Foo::Application.routes.draw do
scope "(:current_brand)", :constraints => { :current_brand => /(foo)|(bar)/ } do
# ... all other routes go here
end
end
I want users to be able to access the site using these URLs:
/foo/some-place
/bar/some-place
/some-place
For convenience, I'm setting up a @current_brand
in my ApplicationController
:
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
before_filter :set_brand
def set_brand
if params.has_key?(:current_brand)
@current_brand = Brand.find_by_slug(params[:current_brand])
else
@current_brand = Brand.find_by_slug('blah')
end
end
end
So far so good, but now I must modify all *_path
and *_url
calls to include the :current_brand
parameter, even though it is optional. This is really ugly, IMO.
Is there some way I can make the path helpers automagically pick up on @current_brand
?
Or perhaps a better way to define the scope in routes.rb
?
Upvotes: 5
Views: 3257
Reputation: 2986
For those arriving here lately, this has changed in Rails 7.1
You can now explicitly set path params as a sub hash of default_url_options in the ApplicationController
class ApplicationController < ActionController::Base
def default_url_options
{ path_params: { account_id: @current_account } }
end
Then you can simply remove the account_id param in your path helper
<%= link_to "Edit", edit_account_path %>
<%= link_to "Account Category", account_categories_path(@current_category)%>
You can always override the default too
<%= link_to "Edit Alt Account", edit_account_path(account_id: @alt_acct_id) %>
(This works for nested routes too if you add more params to the path_params sub-hash)
Upvotes: 0
Reputation: 3011
In addition to CMW's answer, to get it to work with rspec, I added this hack in spec/support/default_url_options.rb
ActionDispatch::Routing::RouteSet.class_eval do
undef_method :default_url_options
def default_url_options(options={})
{ :current_brand => default_brand }
end
end
Upvotes: 4
Reputation: 3144
I think you will want to do something like this:
class ApplicationController < ActionController::Base
def url_options
{ :current_brand => @current_brand }.merge(super)
end
end
This method is called automatically every time url is constructed and it's result is merged into the parameters.
For more info on this, look at: default_url_options and rails 3
Upvotes: 7