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

时间:2010-08-12 14:39:12

标签: ruby-on-rails ruby-on-rails-3 rails-engines applicationcontroller

我正在升级我的Rails插件,使其成为适用于最新3.0RC1版本的引擎,我在确定扩展ActionController的最佳(也是最正确)方法时遇到了一些麻烦。我已经看过DHH this postthis question这里的SO,但我的问题更多是关于如何在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中。

2 个答案:

答案 0 :(得分:10)

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

以下是我一直在使用的内容:


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

另一件事......如果您在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现已弃用,但此大部分文档似乎都是最新的)

答案 1 :(得分:3)

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

您需要在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”无关紧要)创建它们,并将以下内容添加到{{1 }}:

myplugin/lib/extensions/action_controller_base.rb