【问题标题】:Rails 3.0 Engine - Execute code in ActionControllerRails 3.0 引擎 - 在 ActionController 中执行代码
【发布时间】:2011-03-28 23:39:44
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

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

    这是我一直在使用的:

    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 并接受 - 感谢这篇精彩的文章!我感谢您抽出宝贵的时间,即使我自己已经“回答”了。很高兴看到更优雅的解决方案。哦,欢迎来到 Stack Overflow :-)
    【解决方案2】:

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

    您需要在 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 中的任何内容,名称“助手”无关紧要),并将以下内容添加到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
    

    【讨论】:

      猜你喜欢
      • 2015-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-08
      • 2017-12-01
      • 2017-05-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多