25

我发现一些文章解决了消费(父)应用程序无法访问的引擎中的帮助程序问题。为了确保大家都在同一页上,我们说,我们有这样的:Rails 3.1:在客户端应用程序中公开引擎的帮助程序的更好方法

module MyEngine 
    module ImportantHelper 
    def some_important_helper 
     ...do something important... 
    end 
    end 
end 

如果你看一下在“隔离发动机的助手”的rails engine文档(L293),它说:

# Sometimes you may want to isolate engine, but use helpers that are defined for it. 
    # If you want to share just a few specific helpers you can add them to application's 
    # helpers in ApplicationController: 
    # 
    # class ApplicationController < ActionController::Base 
    # helper MyEngine::SharedEngineHelper 
    # end 
    # 
    # If you want to include all of the engine's helpers, you can use #helpers method on an engine's 
    # instance: 
    # 
    # class ApplicationController < ActionController::Base 
    # helper MyEngine::Engine.helpers 
    # end 

所以,如果我问别人消费我的引擎,它添加到他们的application_controller.rb,那么他们将获得所有我重要的辅助方法:

class ApplicationController < ActionController::Base 
    helper MyEngine::ImportantHelper 
end 

这是我想要什么,我但是这很痛苦,特别是如果像我的用例那样,引擎公开的所有内容都可以/应该在消费应用程序的任何地方使用。所以我挖了一下周围越来越发现,我建议做如下的解决方案:

module MyEngine 
    class Engine < Rails::Engine 
    isolate_namespace MyEngine 

    config.to_prepare do 
     ApplicationController.helper(ImportantHelper) 
    end 
    end 
end 

现在,这是正是我想:我所有的ImportantHelper方法添加到父应用程序的应用助手。但是,它不起作用。任何人都可以帮我弄清楚为什么这个更好的解决方案不起作用?

我使用rails 3.1.3运行ruby 1.8.7。如果我错过了与该问题密切相关的任何重要信息,请告知我,并提前致谢。

回答

44

您可以创建一个初始化完成这个像这样:

module MyEngine 
    class Engine < Rails::Engine 
    initializer 'my_engine.action_controller' do |app| 
     ActiveSupport.on_load :action_controller do 
     helper MyEngine::ImportantHelper 
     end 
    end 
    end 
end 
+0

你实际上可以简化更多:helper MyEngine :: ImportantHelper with发送。我更新了我的帖子。 – JDutil 2012-04-06 16:46:16

+0

这个改变了吗?看来,*所有*我的助手都会自动加载,而不需要上面的代码!这是我的引擎:https:// github。com/sientia-jmu/iq_menu – 2012-09-20 07:43:07

+0

看起来好像所有助手都自动包含在每个控制器中,至少在拥有'--full'引擎时。 – 2012-09-27 13:33:03

1
module YourEngine 
    module Helpers 
    def a_helper 
    end 

    ... 
    end 
end 

ActionController::Base.send(:helper, YourEngine::Helpers) 
6

如果你想保持在发动机的代码,而不是每一个实现应用,使用:

module MyEngine 
    class Engine < Rails::Engine 
    isolate_namespace MyEngine 

    config.to_prepare do 
     MyEngine::ApplicationController.helper Rails.application.helpers 
    end 

    end 
end 
1

包含在engine.rb这个代码也有很大的帮助

config.before_initialize do 
    ActiveSupport.on_load :action_controller do 
    helper MyEngine::Engine.helpers 
    end 
end 

基本上你的引擎看起来像

module MyEngine 
    class Engine < Rails::Engine 
    isolate_namespace MyEngine 

    # Here comes the code quoted above 

    end 
end