简体   繁体   English

如何从rails模块访问URL帮助程序

[英]How to access URL helper from rails module

I have a module with a function. 我有一个带功能的模块。 It resides in /lib/contact.rb: 它位于/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. 我想访问模块中的'users_path'之类的URL帮助程序。 How do I do that? 我怎么做?

在您的模块中,只需执行:

 include Rails.application.routes.url_helpers

Delegation to url_helpers seems much better than including the whole module into your model 对url_helpers的委派似乎比将整个模块包含到模型中要好得多

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

reference 参考

Here is how I do it in any context without include 以下是我在没有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 eg this works 如果您尝试include url_helpers - 请确保您在正确的位置执行此操作,例如此方法有效

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 Capybara测试的另一个例子

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

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. 我一直在努力解决帮助者从默认控制器和堆栈( default_url_options等)所期待的细节,并且不想对主机进行硬编码。

Our URL helpers are provided by our nifty module, of course: 我们的URL帮助程序由我们的漂亮模块提供,当然:

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. 但是按原样包含它,并且(1)帮助器将查找default_url_options ,并且(2)将不知道请求主机和请求。

The host part comes from the controller instance's url_options . 主机部分来自控制器实例的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 如果要无缝访问默认URL选项或请求的主机,则需要传递控制器/请求上下文
  • if you just need the path, no host, and don't care about the url options, you can just make some dummy methods. 如果你只需要路径,没有主机,并且不关心url选项,你可以制作一些虚拟方法。
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 对Augustin Riedinger来说,委托代码需要引用url_helpers(复数),否则你就得到了

undefined method `url_helper' 未定义的方法`url_helper'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM