我正在开发Rails插件(它是3.1引擎),名为运营商(https://github.com/stanislaw/carrier)。
在我的一个rails应用程序中,我想用一些新的方法- fx来扩展运营商的控制器。向运营商::MessagesController添加新的操作#comment_form (我希望这个操作只存在于我的应用程序中--我不想将它添加到引擎中,因为它非常具体)。
我在这里看到两种策略:
1)我将{carrier的插件root}/app/controllers/carrier/messages_controller.rb文件复制到我的应用程序的app /控制器/载体/文件夹中,然后扩展它(所有插件的原始操作也被复制到rails应用程序控制器文件夹!)。
2)我想要的更精确的方法--只是创建{我的rails app}/app/controllers/carrier/messages_controller.rb,并且只编写我希望使用的#comment_form方法。
预计两个控制器的内容(从插件的文件夹+自定义在我的rails应用程序中只有新的#comment_form)将叠加,我尝试了第二种方式。但是Rails随后停止了识别所有原始运营商的行为(#index,#show等)它是用messages_controller.rb编写的,是由运营商插件的文件夹编写的,并开始将rails应用程序的messages_controller.rb版本作为唯一的版本(所有原始操作都开始被视为空操作,从而开始通过rails约定默认流程呈现)。
因此,我的一般问题是:如何向Rails引擎控制器添加新的操作,而不将它们完全复制到Rails应用程序/控制器文件夹中?
UPD
现在,我看到了两种解决方案,它们允许在没有严重黑客攻击的情况下扩展引擎控制器(就像这个gem所做的:来自这个线程的https://github.com/asee/mixable_engines:Extending controllers of a Rails 3 Engine in the main app)
1)在#{ YourEngine::Engine.config.root }/app/ your_controller.rb /your文件夹中加载your_controller.rb+“app”+“控制器”+“your_controller”。注意加载而不是要求。
2)设计方法(根据一些主题建议):在主应用程序中创建新控制器,将引擎的一个+编辑路径子类到它们指向这个新控制器。
我仍然相信还有一些更好的解决办法。如果他们这么做了,请纠正我!
发布于 2011-10-10 23:19:14
您的选项2)是好的,因为它将允许您无缝升级宝石。
您的当前方法只是简单地覆盖现有控制器。
假设您想要扩展FooController。
foo_controller_decorator.rb的文件:FooController.class_eval在这里做你的附加代码。端
发布于 2016-07-01 15:20:26
我知道这是一个很老的问题,但如果其他人发现了这个问题,这里有一个宝石,很好地装饰。它将连接到Rails ActiveSupport中,并在进行装饰时添加了一个惯例,以避免循环依赖。我们在多个应用程序上使用它已经有一段时间了。
https://stackoverflow.com/questions/7719633
复制相似问题