84

I have a module with a function. It resides in /lib/contact.rb:

module Contact
  class << self
    def run(current_user)
      ...
    end
  end
end

I want to access the URL helpers like 'users_path' inside the module. How do I do that?

1

5 Answers 5

154

In your module, just perform a :

 include Rails.application.routes.url_helpers
3
  • 3
    Doesn't work for me... :( could you give more details, please? Feb 13, 2014 at 17:58
  • it should be noted that doing that include in a seperate class inside a rails application will erase existing initialized url_helpers causing the error : Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
    – 3pns
    Oct 5, 2018 at 6:54
  • 6
    If you just need it once or twice, you can just use it directly inline, like Rails.application.routes.url_helpers.users_path. I find that more explicit and helpful to others reading your code. Jan 3, 2019 at 20:51
36

Here is how I do it in any context without include

routes = Rails.application.routes.url_helpers
url = routes.some_path

That works in any context. If you're trying to include url_helpers - make sure you are doing that in the right place e.g. this works

module Contact
  class << self
    include Rails.application.routes.url_helpers
  end
end

and this does not work

module Contact
  include Rails.application.routes.url_helpers
  class << self
  end
end

One more example with Capybara tests

feature 'bla-bla' do
  include Rails.application.routes.url_helpers
  path = some_path #unknown local variable some_path
end

and now the right one

include Rails.application.routes.url_helpers
feature 'bla-bla' do
  path = some_path #this is ok
end
33

Delegation to url_helpers seems much better than including the whole module into your model

delegate :url_helpers, to: 'Rails.application.routes' 
url_helpers.users_url  => 'www.foo.com/users'

reference

3
  • should be url_helpers not url_helper, I think.
    – davmac
    Dec 3, 2014 at 12:47
  • Hi there, how did you know it was Rails.application.routes that url_helpers should be delegated to? Where do you find this documentation? Thank you!
    – Nik So
    Dec 9, 2015 at 20:33
  • 1
    @NikSo api.rubyonrails.org is good place to start exploring. Here is documentation for URL helpers api.rubyonrails.org/classes/ActionController/UrlFor.html And including whole module seems overkill, delegation is better option but again its personal opinion :)
    – Naveed
    Dec 10, 2015 at 23:13
8

I've been struggling with the niceties the helper is expecting from the default controller and stack (default_url_options, etc.), and didn't want to hardcode the host.

Our URL helpers are provided by our nifty module, of course:

include Rails.application.routes.url_helpers

But include this as is, and (1) the helper is going to look for default_url_options, and (2) won't know about the request host nor the request.

The host part comes from the controller instance's url_options. Hence, I pass the controller context into my former module, now a class:

class ApplicationController
  def do_nifty_things
    HasAccessToRoutes.new(self).render
  end
end

class HasAccessToRoutes
  include Rails.application.routes.url_helpers
  delegate :default_url_options, :url_options, to: :@context

  def initialize(context)
    @context = context
  end

  def render
    nifty_things_url
  end
end

Might not fit every case, but it's been useful to me when implementing a sort of custom renderer.

In any way:

  • if you want access to the default url options seamlessly, or the host of the request, you need to pass controller/request context in
  • if you just need the path, no host, and don't care about the url options, you can just make some dummy methods.
0
3
delegate :url_helpers, to: 'Rails.application.routes' 
url_helpers.users_url  => 'www.foo.com/users'

to Augustin Riedinger, that delegation code needs to refer to url_helpers (plural), otherwise you get

undefined method `url_helper'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.