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 d开发者_JAVA百科o that?
In your module, just perform a :
include Rails.application.routes.url_helpers
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
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
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.
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'
精彩评论