【问题标题】:How to dynamically call routes helper in rails?如何在rails中动态调用路由助手?
【发布时间】:2012-03-07 05:10:00
【问题描述】:

例如,我构造了一个名为“new_work_path”的字符串,现在我想将该助手作为方法调用。

我试过send("new_work_path", vars) 并从许多对象调用相同的发送。但我认为我没有找到合适的对象来调用这些助手。

要做object.send("new_work_path", vars),我应该寻找什么对象

我已经尝试在网上寻找一段时间,但找不到任何东西。如果有人能在这个上点亮一些灯,那就太好了!

谢谢!

【问题讨论】:

  • Helper 方法只能从视图上下文中调用,如果您正在尝试这样做,则不能从模型中调用。您能否更具体地说明您要在哪里执行此操作?如果你有正确的上下文,一个标准的send 调用就足够了。
  • 我正在尝试在 application_helper 中执行此操作,标准路由助手调用将正常运行。
  • 那么您遇到的错误是什么?你可以发布一个例子吗?如果直接调用new_work_path 有效,那么send(:new_work_path) 应该是等价的。
  • 哇,这次成功了。那时我一定是第一次错过了什么。确实 send(:new_work_path) 就是这样工作的。现在我对自己的愚蠢感到恼火。哈哈谢谢!
  • 我如何关闭问题?

标签: ruby-on-rails ruby routes


【解决方案1】:

试试Rails.application.routes.url_helpers.send(...)

编辑:

由于 Larry Gebhardt mentioned url_helpers 模块不再被缓存。

另一种解决方法是:

cached_helpers = Class.new do
  include Rails.application.routes.url_helpers
  include Rails.application.routes.mounted_helpers
end.new

cached_helpers.send(...)

【讨论】:

  • 效果很好。值得“最佳答案”:)
  • 这很好用。假设你想链接到一个嵌套资源,你可以写Rails.application.routes.url_helpers.send("new_#{@model.class.name.downcase}_comment_url", "#{@model.class.name.downcase}_id".to_sym => @model),因为你需要一个父model_id
  • 如果您尝试从已安装的Rails::Engine 访问url_helpers,请尝试"<EngineName>::Engine".constantize.routes.url_helpers.send(...)' where `来自您的mount 文件中的mount 行。
  • 我相信这个答案不再被认为是有效的。 Rails 不再缓存url_helpers 返回的匿名模块。这可能会导致生成大量包含辅助方法的模块。见github.com/rails/rails/commit/…
  • 似乎在 rails 6.1 中缓存了 url_helpers was brought back
【解决方案2】:

我的错,按照@tadman 的建议,我再次尝试使用send(:new_work_path, args),它成功了!一定是之前打错了。

在发现 send 立即生效之前,我找到了另一个有趣的解决方案:

new_polymorphic_path(Work, args)

这似乎也提供了一些语法糖。

【讨论】:

  • 多态路径很好玩,你也可以做polymorphic_path(:foo)或者polymorphic_path("bar")
【解决方案3】:

我对已接受答案的两分钱。
请始终牢记sendis a risky command,如果可能,您应该避免,或者至少有一个可用选项的白名单,以便您的send 电话接受。如果您不想使用它,Rails 有its own way 可以使用.url_for 动态获取路径:

[5] pry(main)> include Rails.application.routes.url_helpers
=> Object
[6] pry(main)> url_for(controller: 'one_path/the_controller', action: 'valid_path')
=> "http://localhost:3000/one_path/the_controller/valid_path"
[7] pry(main)> url_for(controller: 'one_path/the_controller', action: 'some_h4cky_thing')
ActionController::UrlGenerationError: No route matches {:action=>"some_h4cky_thing", :controller=>"one_path/the_controller"}

.link_to 也为此目的提供了自己的内置选项:

<%= link_to "A link to #{option}", {controller: 'one_path/the_controller', action: option}, target: '_blank' %>

【讨论】:

    猜你喜欢
    • 2013-05-09
    • 2013-02-27
    • 1970-01-01
    • 1970-01-01
    • 2016-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-27
    相关资源
    最近更新 更多