我正在开发名为 Carrier ( https://github.com/stanislaw/carrier ) 的 Rails 插件(它是 3.1 引擎)。
在我的一个 Rails 应用程序中,我想用一些新方法来扩展 Carrier 的控制器 - fx。向 Carrier::MessagesController 添加新操作 #comment_form(我希望此操作仅存在于我的应用程序中 - 我不想将其添加到引擎中 - 因为它非常具体)。
我在这里看到的两种策略:
1)我将 {Carrier's plugin root}/app/controllers/carrier/messages_controller.rb 文件复制到我的应用程序的 app/controllers/carrier/ 文件夹,然后扩展它(所有插件的原始操作也复制到 rails app controllers 文件夹! )。
2)我想要的更准确的方法 - 只是创建 {My rails app}/app/controllers/carrier/messages_controller.rb 并只编写我希望扩展 Carrier 的#comment_form 方法。
期望两个控制器的内容(来自插件文件夹的原始内容+我的 Rails 应用程序中只有新的#comment_form 的自定义)会叠加,我尝试了第二种方法。但是Rails随后停止识别Carrier插件文件夹中messages_controller.rb中写入的所有原始Carrier操作(#index,#show等),并开始将rails应用程序的messages_controller.rb版本视为唯一一个(所有原始操作都开始处理为空,因此开始通过 rails 约定的默认流程呈现)。
所以我的一般问题是:如何在不将它们完全复制到 Rails app/controllers 文件夹的情况下向 Rails Engines 控制器添加新操作?
UPD
现在我看到两个解决方案,它们允许扩展引擎的控制器而没有严重的黑客攻击(就像这个 gem 所做的那样:https ://github.com/asee/mixable_engines来自这个线程:Extending controllers of a Rails 3 Engine in the main app)
1) 在 #{main_app}/app/controller/your_engine 文件夹中的 your_controller.rb 中加载 YourEngine::Engine.config.root + 'app' + 'controllers' + 'your_controller'。注意load而不是 require。
2)设计方式(根据一些SO主题建议):在主应用程序中创建新控制器,将引擎的一个子类+编辑路由指向这个新控制器。
我仍然确信存在一些更好的解决方案。如果他们这样做,请纠正我!