代码之家  ›  专栏  ›  技术社区  ›  Topher Fangio

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

  •  5
  • Topher Fangio  · 技术社区  · 15 年前

    我正在升级我的Rails插件,使其成为一个与最新的3.0RC1版本兼容的引擎,我很难找到最佳(也是最正确)的扩展方法。 ActionController . 我见过 this post 由DHH和 this question 不过,我的问题更多的是如何在 动作控制器 .

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

    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
    

    我知道如何正确地包含我的两个私有函数,但我找不到一种方法让它正确地调用 helper , before_filter after_filter .

    我将非常感谢一些链接或一种方法,使这项工作。我试过给我的控制器命名除了 ApplicationController 拥有真正的 应用程序控制器 扩展它,但这似乎也不起作用。我真的很期待任何能让发动机用户的生活尽可能简单的解决方案。理想情况下,他们不必扩展我的类,但他们将所有的功能都内置到自己的类中。 应用程序控制器 .

    2 回复  |  直到 11 年前
        1
  •  10
  •   johnmcaliley    14 年前

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

    以下是我一直在使用的:

    
    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 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应用程序中的应用程序控制器和应用程序助手。同样,这只是个人偏好,但是我尝试将任何与Rails直接相关的东西,比如控制器、助手和模型放在/my_engine/app中,以及与插件相关的任何东西放在/my_engine/lib中。

    有关初始值设定项的详细信息,请参阅Jose Valim的本教程: https://gist.github.com/e139fa787aa882c0aa9c (现在不推荐使用引擎名,但大多数文档似乎是最新的)

        2
  •  3
  •   Topher Fangio    15 年前

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

    您需要在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 :

    require 'helpers/helper_file_1'
    require 'helpers/helper_file_2'
    
    ActionView::Base.send :include, MyHelper1
    ActionView::Base.send :include, MyHelper2
    
    推荐文章