Rails 3.0引擎 – 在ActionController中执行代码

我正在升级我的Rails插件,使其成为最新3.0RC1版本的引擎,并且我在找出扩展ActionController的最佳(也是最正确的)方法时遇到了一些麻烦。 我已经在DHH上看过这篇文章了, 这个问题在这里,但是我的问题更多的是关于如何在ActionController正确调用代码。

例如,我需要在我的引擎控制器中调用以下内容:

 class ApplicationController < ActionController::Base helper :all before_filter :require_one_user after_filter :store_location private def require_one_user # Code goes here end def store_location # Code goes here end end 

我知道如何正确地包含我的两个私有函数,但我找不到一种方法来正确调用helperbefore_filterafter_filter

我非常感谢一些链接或方法来使这项工作。 我已经尝试将我的控制器命名为ApplicationController其他东西,并让真正的ApplicationController扩展它,但这似乎也不起作用。 我真的很想找到能让发动机用户的生活变得尽可能简单的任何解决方案。 理想情况下,他们不必扩展我的类,但他们拥有内置于自己的ApplicationController所有function。

您可能还想查看引擎子类中的初始化器,因此您不必在控制器类中包含视图助手。 这将使您可以控制这些模块的加载顺序。

这是我一直在使用的:

module MyEngine class Engine < Rails::Engine initializer 'my_engine.helper' do |app| ActionView::Base.send :include, MyEngineHelper end initializer 'my_engine.controller' do |app| ActiveSupport.on_load(:action_controller) do include MyEngineActionControllerExtension end end end end
module MyEngine class Engine < Rails::Engine initializer 'my_engine.helper' do |app| ActionView::Base.send :include, MyEngineHelper end initializer 'my_engine.controller' do |app| ActiveSupport.on_load(:action_controller) do include MyEngineActionControllerExtension end end end end 

此外,动作控制器扩展的另一个选项是使用mixin模块。 这将让你使用before_filter,after_filter等。

module MyEngineActionControllerExtension def self.included(base) base.send(:include, InstanceMethods) base.before_filter :my_method_1 base.after_filter :my_method_2 end module InstanceMethods #........... end end
module MyEngineActionControllerExtension def self.included(base) base.send(:include, InstanceMethods) base.before_filter :my_method_1 base.after_filter :my_method_2 end module InstanceMethods #........... end end 

另一件事......如果您在gem的顶层创建默认的rails目录,则不必担心需要帮助程序或控制器。 您的引擎子类可以访问它们。 所以我在这里添加我的应用程序控制器和应用程序助手扩展

 /myengine/app/helpers/myengine_application_helper_extension.rb
 /myengine/app/controllers/my_engine_action_controller_extension.rb

我喜欢这个设置,因为它看起来类似于rails应用程序中的application_controller和application_helper。 同样,这只是个人偏好,但我尝试保留任何直接与rails相关的内容,例如/ my_engine / app中的控制器,帮助器和模型以及与/ my_engine / lib中的插件相关的任何内容

有关初始化程序的更多信息,请查看Jose Valim的本教程: https ://gist.github.com/e139fa787aa882c0aa9c(engine_name现已弃用,但此大部分文档似乎是最新的)

所以,我终于找到了解决方案,我希望它可以帮助其他人。

您需要在lib目录中创建一个文件,因为您实际上是要扩展该类。 我做了myplugin/lib/extensions/action_controller_base.rb

然后,在myplugin/lib/myplugin.rb文件中,执行以下操作:

 require 'extensions/action_controller_base.rb' 

myplugin/lib/extensions/action_controller_base.rb放了以下内容:

 require 'action_controller' # Make sure ActionController::Base is defined ActionController::Base.class_eval { private def my_method_1 # Code Goes Here end def my_method_2 # Code Goes Here end } ActionController::Base.instance_eval { helper_method :my_method_1, :my_method_2 before_filter :my_method_1 after_filter :my_method_2 } 

如果你需要有视图助手,在myplugin/lib/helpers目录中创建它们(或者lib里面的任何东西,名字“helpers”也没关系),并将以下内容添加到myplugin/lib/extensions/action_controller_base.rb的底部myplugin/lib/extensions/action_controller_base.rb

 require 'helpers/helper_file_1' require 'helpers/helper_file_2' ActionView::Base.send :include, MyHelper1 ActionView::Base.send :include, MyHelper2