我创建了一个简单的Rails引擎,为应用程序提供了一些通用功能(照片库)。我希望能够覆盖标准_header部分,以便库的菜单与我的主应用程序的菜单匹配。在我的标题视图中,我调用了一个帮助程序,它是application_helpers(主应用程序)的一部分,但我不断收到“未定义的方法”错误。据我所知,当我覆盖引擎应用程序布局或其部分时,主应用程序application_helpers没有被包括(显然)。
所以我的问题是,如何覆盖主应用程序中的引擎视图,并获得对主应用程序帮助器方法的访问权限?我仍然需要访问引擎帮助程序,而不是搞砸引擎功能。
我是否还需要覆盖控制器?得到一些帮助似乎很多。
由于
Rails 3.1.3
答案 0 :(得分:3)
查看此博文:http://www.candland.net/2012/04/17/rails-routes-used-in-an-isolated-engine/ 作者将一个method_missing定义添加到应用程序助手中,以便访问父应用程序的助手。
/config/initializers/blogit.rb
module Blogit
module ApplicationHelper
def method_missing method, *args, &block
puts "LOOKING FOR ROUTES #{method}"
if method.to_s.end_with?('_path') or method.to_s.end_with?('_url')
if main_app.respond_to?(method)
main_app.send(method, *args)
else
super
end
else
super
end
end
def respond_to?(method)
if method.to_s.end_with?('_path') or method.to_s.end_with?('_url')
if main_app.respond_to?(method)
true
else
super
end
else
super
end
end
end
end
答案 1 :(得分:2)
尝试包含主要的app帮助程序方法。例如:
class MyEngineClass
include ApplicationHelper
#...
end
您可能需要先请求该文件,但我希望Rails能够在这种情况下正确找到它。
包含ApplicationHelper后,您应该可以直接在控制器中使用这些帮助程序。
看起来你可以为很多Rails类调用ClassName.helper("application")
- 不确定这是否适用于此。
答案 2 :(得分:1)
尝试在您的应用程序中创建一个帮助程序,并在引擎中使用相同的帮助程序名称来覆盖引擎辅助程序方法。
我发现this discussion特别有见地。在{em>隔离引擎帮助下的Rails Engine API docs中也有一些有趣的想法。
答案 3 :(得分:1)
引擎应该独立于主应用程序,这就是您无法从引擎访问其帮助程序的原因。
但是,有一些黑客方法可以让您的引擎访问主应用程序的帮助程序。我就这样做了:
# In the main app
# initializers/share_helpers_path_with_engine.rb
PhotoGallery::Engine.class_eval do
paths["app/helpers"] << File.join(File.dirname(__FILE__), '../..', 'app/helpers')
end
您当然需要将PhotoGallery
更改为引擎类的实际名称。
请随意查看引擎文档(有关路径的部分):http://edgeapi.rubyonrails.org/classes/Rails/Engine.html
答案 4 :(得分:0)
免责声明:我只在Rails 3.2引擎中使用此解决方案。
如果您的引擎中有标准标题部分 vendor / gems / my_gallery_engine / app / views / application / _header.html.erb 。
然后,通过创建自定义的部分 app / views / application / _header.html.erb ,在主应用中覆盖它。
覆盖有效,因为Rails的视图模板搜索路径(默认情况下)以主应用的 app / views 目录开头,然后搜索引擎的 app / views 按加载顺序。
所有主要应用程序的助手都将在部分内容中使用。