我正在尝试从rails 4引擎扩展ActionController::Base
,以便任何安装它的应用程序在每个操作之前运行特定方法。现在我明白可能有几种不同的方法可以做到这一点,例如关注点,class_eval
或者对它进行开放式分类,但是我对这一切都很新,我能找到的链接主要是关于如何扩展引擎控制器主应用程序,而不是像我想要的那样。
这是我尝试过的,我已经在我的引擎的controllers文件夹中创建了一个新文件夹,如下所示:
my_engine
|-- app
|-- controllers
|-- action_controller
|-- base_controller.rb
|-- my_engine
|-- some_controller.rb
|-- other_controller.rb
并在base_controller.rb
我添加了以下内容:
require_dependency "action_controller/base"
module ActionController
class BaseController
before_action :some_method
private
def some_method
#just for testing
redirect_to 'http://www.google.com'
end
end
end
这不起作用。我认为这是因为它没有被加载(我仍然试图了解在rails引擎中如何以及在何处放置这样的自定义代码),所以我尝试将该代码复制到my_engine/lib/my_engine/engine.rb
文件但是然后启动服务器时出现以下错误:
undefined method `before_action' for ActionController::BaseController:Class (NoMethodError)
如何做到这一点,我应该在哪里正确放置文件?
答案 0 :(得分:2)
可以从引擎Engine
类中轻松实现,例如:
class Engine < ::Rails::Engine
ActionController::Base.class_eval do
include Some::Module
end
end
然而,这种方法意味着Some::Module
中的任何更改都需要服务器重新启动才能加载该更改。它可能很烦人,所以使用简单的OOP继承可能会更好地解决这个问题。
在这种情况下,引擎会为某些控制器提供逻辑,让我们称之为EngineController
。现在,控制器层次结构如下所示:
class EngineController < ActionController::Base; end # provided with an engine
class MainAppController < EngineController; end