如何正确扩展 Rails Engine 的控制器?

Sta*_*ich 4 ruby-on-rails ruby-on-rails-plugins rails-engines ruby-on-rails-3.1

我正在开发名为 Carrier ( https://github.com/stanislaw/carrier ) 的Rails 插件(它是 3.1 引擎)。

在我的一个 rails 应用程序中,我想用一些新方法扩展 Carrier 的控制器 - fx。将新操作 #comment_form 添加到 Carrier::MessagesController(我希望此操作仅存在于我的应用程序中 - 我不想将其添加到引擎中 - 因为它非常具体)。

我在这里看到的两种策略:

1)我将{Carrier's plugin root}/app/controllers/carrier/messages_controller.rb文件复制到我的应用程序的app/controllers/carrier/文件夹中,然后扩展它(所有插件的原始操作也被复制到rails应用程序控制器文件夹中! )。

2)我想要的更准确的方法 - 只是创建 {My rails app}/app/controllers/carrier/messages_controller.rb 并只写#comment_form 方法,我希望 Carrier 扩展。

期望两个控制器的内容(来自插件文件夹+自定义在我的 Rails 应用程序中只有新的#comment_form)会叠加,我尝试了第二种方式。但是 Rails 然后停止识别来自 Carrier 插件文件夹的 messages_controller.rb 中写入的所有原始 Carrier 操作(#index、#show 等...),并开始将 Rails 应用程序的 messages_controller.rb 版本视为唯一一个(所有原始操作都开始处理为空,因此开始通过 Rails 约定的默认流程呈现)。

所以我的一般问题是:如何将新操作添加到 Rails Engines 控制器而不将它们完全复制到 Rails app/controllers 文件夹?

UPD

现在,我看到了两种解决方案,它们允许在没有严重黑客攻击的情况下扩展引擎的控制器(就像这个 gem 所做的那样:https : //github.com/asee/mixable_engines来自这个线程:在主应用程序中扩展 Rails 3 引擎的控制器

1) 在 #{main_app}/app/controller/your_engine 文件夹中的 your_controller.rb 中加载 YourEngine::Engine.config.root + 'app' + 'controllers' + 'your_controller'。注意负载而不是要求。

2)设计方式(根据一些SO主题建议):在主应用程序中创建新控制器,该控制器将引擎的一个子类化+编辑路由到它们指向这个新控制器。

我仍然确信存在一些更好的解决方案。如果他们这样做,请纠正我!

apn*_*ing 5

您的选项 2) 很好,因为它可以让您无缝升级 gem。

您当前的方式只是覆盖现有的控制器。

假设您要扩展FooController.

  1. 创建一个foo_controller_decorator.rb在初始化文件夹中命名的文件

  2. 在文件中:

FooController.class_eval do
  #your additionnal code here.
end
Run Code Online (Sandbox Code Playgroud)