17

As ActionController::Base#default_url_options is deprecated, I wonder how to set default url options in rails3. The default url options are not static but dependent of the current request.

http://apidock.com/rails/ActionController/Base/default_url_options

Thanks, Corin

gucki
  • 4,582
  • 7
  • 44
  • 56
  • `ActionController::Base#default_url_options` [is *not* deprecated](http://edgeguides.rubyonrails.org/action_controller_overview.html#default-url-options). – Mohamad Aug 01 '15 at 14:10

5 Answers5

26

To set url options for current request use something like this in your controller:

class ApplicationController < ActionController::Base

  def url_options
    { :profile => current_profile }.merge(super)
  end

end

Now, :profile => current_profile will be automerge to path/url parameters.

Example routing:

scope ":profile" do
  resources :comments
end

Just write:

comments_path

and if current_profile has set to_param to 'lucas':

/lucas/comments
Łukasz Śliwa
  • 600
  • 4
  • 16
  • Thanks! Is this the "official" rails 3.0/3.1 way? – gucki Jun 05 '11 at 19:34
  • Too bad, it throws an exception when it's declared as protected which is a must (otherwise it's exposed as an action). So it does not work. – gucki Jun 06 '11 at 17:33
  • 4
    It works for me in real project, I don't know why you think it exposes as an action, just remove default routing /:controller/(:action) from your routes. This method must be public. – Łukasz Śliwa Jun 08 '11 at 16:33
  • It's also working for mailers, just define the method in your subclass of ActionMailer::Base :) – gucki Dec 29 '11 at 09:42
  • How would you set the options based on model attribute. For example, set `:profile` to `comment.user.city_name`, so we get `/newyork/comments/123`? – QWJ QWJ Sep 12 '13 at 05:58
  • comments_path(:profile => comment.user.city_name, :id => comment.id) – Łukasz Śliwa Sep 12 '13 at 09:28
  • @LukaszSliwa but how would you set the instance variable to for `current_profile`? – Mohamad Feb 10 '14 at 15:23
24

I believe the preferred method is to now tell the router to handle this:

Rails.application.routes.default_url_options[:foo]= 'bar' 

You can put this line in either routes.rb or an initializer. Whichever you would prefer. You could even put it in your environment configs if the values change based on your environment.

Andrew
  • 227,796
  • 193
  • 515
  • 708
Dylan Markow
  • 123,080
  • 26
  • 284
  • 201
  • 1
    But how can i make this dependent on the current request, so for example access instance variables? – gucki May 23 '11 at 18:23
  • Yeps, it's not thread safe. I did it through custom method and Thread.current – Dmitry Polushkin Aug 15 '11 at 17:05
  • 2
    Looks like this is it for Rails 3.2. – aceofspades Mar 19 '12 at 18:34
  • 14
    Dumb question: where do you *put* this line? In routes.rb? In an initializer? – Dan Tao Jul 30 '13 at 14:31
  • If you have to set this at the config level, how do you pass in a dynamic `account_id`? For example `scope '/:account_id'` - How would you be able to set `account_id` dynamically at the config level? – Mohamad Feb 13 '14 at 14:06
  • I just put this in the Application Controller and it worked for me. Not sure if that is the right place for it, but it works. – nfriend21 Jun 03 '14 at 21:11
  • @DanTao You can put this line in either `routes.rb` or an initializer. Whichever you would prefer. You could even put it in your environment configs if the values change based on your environment. – Andrew Dec 11 '14 at 19:51
  • This no longer works for Rails 5.1.4 for page rendering, but only works for rails console. – lulalala Feb 14 '18 at 08:44
4

That apidock.com link is misleading. default_url_options is not deprecated.

http://guides.rubyonrails.org/action_controller_overview.html#default_url_options

Jason Heiss
  • 671
  • 6
  • 11
0

For Rails 3 specifically, the canonical way to do it is by adding a default_url_options method to your ApplicationController.

class ApplicationController < ActionController::Base
  def default_url_options
    {
        :host => "corin.example.com",
        :port => "80"  #  Optional. Set nil to force Rails to omit
                       #    the port if for some reason it's being
                       #    included when you don't want it.
    }
  end
end

I just had to figure this out myself, so I know it works.

This is adapted from the Rails 3 Guide:
http://guides.rubyonrails.org/v3.2.21/action_controller_overview.html#default_url_options

Grant Birchmeier
  • 17,809
  • 11
  • 63
  • 98
0

Rails.application.routes.default_url_options[:host]= 'localhost:3000'

In the developemnt.rb / test.rb, can be more concise as following:

Rails.application.configure do
  # ... other config ...

  routes.default_url_options[:host] = 'localhost:3000'
end
Derek Fan
  • 817
  • 11
  • 10