已安装的轨道引擎中的命名路线
Posted
技术标签:
【中文标题】已安装的轨道引擎中的命名路线【英文标题】:Named routes in mounted rails engine 【发布时间】:2011-12-23 04:08:07 【问题描述】:我正在制作一个像这样安装的小型轨道引擎:
mount BasicApp::Engine => "/app"
使用this answer我已经验证引擎中的所有路由都应该是:
但是 - 当我(在引擎内部)链接到命名路由(在引擎内部定义)时,我收到此错误
undefined local variable or method `new_post_path' for #<#<Class:0x000000065e0c08>:0x000000065d71d0>
运行“rake route”清楚地验证“new_post”应该是一个命名路径,所以我不知道为什么 Rails (3.1.0) 无法弄清楚。欢迎任何帮助
我的 config/route.rb(用于引擎)如下所示
BasicApp::Engine.routes.draw do
resources :posts, :path => '' do
resources :post_comments
resources :post_images
end
end
我应该补充一点,它是独立的引擎。但是 main_app.root_path 之类的路径可以正常工作 - 而 root_path 则不行
【问题讨论】:
如果您来到这里是因为您在使用 Blogit gem 时遇到问题 - 您可以忽略以下解决方案(适用于其他应用程序)并转到您的 blogit.rb 文件并取消注释该行说:config.inline_main_app_named_routes = true 【参考方案1】:正确的方法
我相信最好的解决方案是在引擎的路由代理上调用new_post_path
,它可以作为辅助方法使用。在您的情况下,助手方法将默认为basic_app_engine
,因此您可以在视图或助手中调用basic_app_engine.new_post_path
。
如果需要,您可以通过以下两种方式之一设置名称。
# in engine/lib/basic_app/engine.rb:
module BasicApp
class Engine < ::Rails::Engine
engine_name 'basic'
end
end
或
# in app/config/routes.rb:
mount BasicApp::Engine => '/app', :as => 'basic'
在任何一种情况下,您都可以在您的视图或助手中调用basic.new_posts_path
。
另一种方式
另一种选择是不使用已安装的引擎,而是让引擎将路线直接添加到应用程序。 Thoughtbot's HighVoltage 这样做。我不喜欢这个解决方案,因为当你添加许多引擎时它可能会导致命名空间冲突,但它确实有效。
# in engine/config/routes.rb
Rails.application.routes.draw do
resources :posts, :path => '' do
resources :post_comments
resources :post_images
end
end
# in app/config/routes.rb:
# (no mention of the engine)
【讨论】:
如果您想从引擎内部访问主应用程序的命名路由怎么办? @jphager2 你会打电话给 main_app 吗? 不知道助手存在。非常便利。谢谢! 自 3.1 起在 rails engine routes guides 中有详细记录【参考方案2】:在 Rails 4 上,engine_name
指令对我不起作用。
为了从引擎自己的视图或控制器访问引擎路由中定义的命名路由,我最终使用了详细
BasicApp::Engine.routes.url_helpers.new_post_path
我建议定义一个简单的辅助方法以使其更有用
# in /helpers/basic_app/application_helper.rb
module BasicApp::ApplicationHelper
def basic_app_engine
@@basic_app_engine_url_helpers ||= BasicApp::Engine.routes.url_helpers
end
end
有了这个,你现在可以使用了
basic_app_engine.new_post_path
如果您需要从引擎访问您的主应用程序助手,您可以使用main_app
:
main_app.root_path
【讨论】:
AFAIKBasicApp::Engine.routes.url_helpers
生成一个新的Module
并在您每次调用它时定义所有路径/url 帮助器方法。它很快就会成为性能和内存问题。所以我建议将它包含在你想使用它的类中。
@tmichel 是对的,必须使用 memoization 来避免在调用时生成模块。尝试(未经测试!)return @@basic_app_engine_url_helpers ||= BasicApp::Engine.routes.url_helpers
上述“正确方式”的解决方案都不适合我。将引擎路由安装为“在您的应用中使用以下内容访问引擎路线
MyApp::Engine.routes.url_helpers.new_post_path
【讨论】:
不要这样做,它会在每次调用时重新生成 url_helpers 模块,最好在辅助方法中将结果存储到所需范围内的变量中。正如@Epigene 展示的那样以上是关于已安装的轨道引擎中的命名路线的主要内容,如果未能解决你的问题,请参考以下文章