Ruby on rails Rails 3.1:暴露引擎的更好方法&x27;客户端应用程序中的帮助程序

Ruby on rails Rails 3.1:暴露引擎的更好方法&x27;客户端应用程序中的帮助程序,ruby-on-rails,ruby-on-rails-3.1,rails-engines,helpers,view-helpers,Ruby On Rails,Ruby On Rails 3.1,Rails Engines,Helpers,View Helpers,我发现有几篇文章讨论了引擎中的助手无法被消费(父)应用程序访问的问题。为了确保我们都在同一页上,假设我们有: module MyEngine module ImportantHelper def some_important_helper ...do something important... end end end 如果您查看“隔离引擎的帮助”(L293)中的文档,它会说: # Sometimes you may want to isolate en

我发现有几篇文章讨论了引擎中的助手无法被消费(父)应用程序访问的问题。为了确保我们都在同一页上,假设我们有:

module MyEngine
  module ImportantHelper
    def some_important_helper
      ...do something important...
    end
  end
end
如果您查看“隔离引擎的帮助”(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
#有时您可能希望隔离引擎,但请使用为其定义的帮助程序。
#如果您只想共享几个特定的帮助程序,可以将它们添加到应用程序的
#ApplicationController中的帮助程序:
#
#类ApplicationController
因此,如果我要求任何使用我的引擎的人将此添加到他们的应用程序_controller.rb中,那么他们将可以访问我的所有重要助手方法:

class ApplicationController < ActionController::Base
  helper MyEngine::ImportantHelper
end
class ApplicationController
这正是我想要的,它可以工作,但这是一种痛苦,特别是如果,就像我的用例一样,引擎公开的所有内容都可以/应该在消费应用程序中的任何地方使用。因此,我进一步研究了一下,找到了一个解决方案,建议我执行以下操作:

module MyEngine
  class Engine < Rails::Engine
    isolate_namespace MyEngine

    config.to_prepare do
      ApplicationController.helper(ImportantHelper)
    end
  end
end
模块MyEngine
类引擎
现在这正是我想要的:将我所有的ImportantHelper方法添加到父应用程序的应用程序助手中。但是,它不起作用。有谁能帮我找出为什么这个更好的解决方案不起作用


我正在运行ruby 1.8.7和rails 3.1.3。如果我遗漏了与此问题相关的任何重要信息,请通知我,并提前感谢。

您可以创建一个初始值设定项来完成此操作,如下所示:

module YourEngine
  module Helpers
    def a_helper
    end

    ...
  end
end

ActionController::Base.send(:helper, YourEngine::Helpers)
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
模块MyEngine
类引擎
我已经写了两篇关于从头开始创建引擎的博文,在这些博文之后,一切都应该按照预期工作(不需要额外的配置)。也许您仍然对以下方面感兴趣:


更新:同时还有三篇文章,还有一些信息要发布。请给我反馈。

如果希望将代码保留在引擎中,而不是每个实现的应用程序中,请使用以下命令:

module MyEngine
  class Engine < Rails::Engine
    isolate_namespace MyEngine

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

  end
end
模块MyEngine
类引擎
将此代码包含在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
模块MyEngine
类引擎
实际上,无需发送,您可以将其简化为:helper MyEngine::ImportantHelper。我已经更新了我的帖子。这有变化吗?似乎我所有的助手都是自动加载的,没有上面的代码!这是我的引擎:看起来每个控制器都会自动包含所有的助手,至少在有一个
--full
引擎的情况下是这样的。自从我最初发布这篇文章以来,它可能已经发生了变化,但当时它是必需的。我认为如果引擎被隔离,它们不会被加载,删除
isolate_namespace MyEngine
意味着它们会被加载,但当然还有其他副作用。链接已失效:/