如何从 Rails 模块访问 URL 助手

我有一个带函数的模块,它位于/lib/contact.rb:

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

我想访问模块内部的 URL 帮助程序,比如“ users _ path”?

54110 次浏览

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

 include Rails.application.routes.url_helpers

将代理委托给 url _ helpers 似乎比将整个模块包含到模型中要好得多

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

参考文献

下面是我在没有 include的情况下是如何做到的

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

这在任何情况下都行得通。如果你正在尝试 include url _ helpers-确保你在正确的地方这样做,例如这个工作

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

这样不行

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

再举一个水豚测试的例子

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

现在是正确的

include Rails.application.routes.url_helpers
feature 'bla-bla' do
path = some_path #this is ok
end
delegate :url_helpers, to: 'Rails.application.routes'
url_helpers.users_url  => 'www.foo.com/users'

到 Augustin Riedinger,该代理代码需要引用 url _ helpers (复数) ,否则将得到

未定义的方法‘ url _ helper’

我一直在纠结于 helper 对默认控制器和堆栈(default_url_options等)的期望,而不想对主机进行硬编码。

当然,我们的 URL 帮助程序是由我们的漂亮模块提供的:

include Rails.application.routes.url_helpers

但是按原样包含它,(1)助手将查找 default_url_options,(2)将不知道请求主机和请求。

主机部分来自控制器实例的 url_options。因此,我将控制器上下文传递到以前的模块,现在是一个类:

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

可能不适用于所有情况,但是它对我实现一种自定义渲染器很有用。

以任何方式:

  • 如果希望无缝地访问默认 URL 选项或请求的主机,则需要将控制器/请求上下文传递到
  • 如果您只需要路径,没有主机,也不关心 url 选项,那么您可以创建一些虚拟的方法。