从RailsEngine访问应用程序帮助程序

问题描述 投票:1回答:5

我有安装引擎的Rails应用程序。

#{main_app}/config/routes.rb
mount CommentIt::Engine => "/talk", :as => 'comment_it'

并希望在主应用程序布局中打开引擎视图。

#{main_app}/app/views/layouts/application.html.erb
<html>
  <body>
    <%= link_to "users", users_path %>
    <%= yield %>
  </body>
</html>

当访问引擎视图(0.0.0.0:3000/talk)时,我得到错误'未定义方法`users_path'用于#<#:0x007f9dbf0f7800>'users_path在主应用程序视图中正常工作。在访问Engine页面时,如何从主应用程序获取路径助手?

ruby-on-rails rails-engines
5个回答
3
投票

从Rails 3.2开始,唯一的方法是将引擎转换为“完整”引擎而不是可安装引擎。在可安装引擎中,引擎不了解主机应用程序,并且默认情况下无法访问其路径/ URL帮助程序。

This answer解释了需要做什么,这对我有用。

另一种方法是遍历主机应用程序的文件,并将适当的视图/应用程序助手包含在引擎中。它有效,但对我来说这太麻烦了。简单地转换为完整的引擎就可以了。


4
投票

我还不确定这可能有多聪明,但是刚刚发现以下内容适用于我正在研究的可安装/隔离引擎:

# in app/helpers/my_engine/application_helper.rb
module MyEngine
  module ApplicationHelper
    def method_missing(method, *args, &block)
      main_app.send(method, *args, &block)
    rescue NoMethodError
      super
    end
  end
end

思考?


2
投票

如果要从主应用程序访问引擎辅助程序,可以使用在安装时为应用程序创建的名称。

在主应用程序的config / routes.rb中:

MyApplication::Application.routes.draw do
  mount MyEngine::Engine => "/some_engine", :as => "some_engine"
  get "/path_i_want_to_reference_from_main_app" => "some_controller#some_action"
end

内部主应用程序控制器/视图:

some_engine.path_i_want_to_reference_from_main_app_path

所以在你的情况下你会使用:

<%= link_to "users", comment_it.users_path %>

如果要从引擎访问主应用程序助手,请尝试main_app.users_path

http://edgeapi.rubyonrails.org/classes/Rails/Engine.html


2
投票

要从引擎的视图访问主应用程序助手(ApplicationHelper),我尝试包括:

应用程序/佣工/ your_engine / application_helper.rb

module YourEngine
  module ApplicationHelper
    include ActionView::Helpers::ApplicationHelper
  end
end

它工作,但有一次,当我重新启动开发服务器时,它抛出uninitialized constant ActionView::Helpers::ApplicationHelper,但我无法重现此异常。

编辑

删除了这个include并制作了这个:

lib / my_engine / engine.rb(它在引擎内部)

module MyEngine
  class Engine < ::Rails::Engine
    isolate_namespace MyEngine
    config.to_prepare do
      ApplicationController.helper(ActionView::Helpers::ApplicationHelper)
    end
  end
end

1
投票

在我的情况下,我的宝石里面有MyCustomEngineController,它继承了ApplicationController,就像这样:

module MyEngine
  class MyCustomEngineController < ApplicationController

#...

我稍微改变了这个继承:

module MyEngine
  class MyCustomEngineController < ::ApplicationController

#...

(在::之前注意ApplicationController

现在我所有应用程序的帮助程序都可用于我的引擎视图

© www.soinside.com 2019 - 2024. All rights reserved.