5

我正在升級我的Rails插件,使其成爲最新的3.0RC1版本的引擎,並且我很難找出最佳(並且最正確)的方式來擴展ActionController。我見過DHH的this postthis question,但我的問題更多的是關於如何在ActionController內正確調用代碼。Rails 3.0引擎 - 在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中。

回答

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 
 

此外,另一種選擇的動作控制器擴展使用一個混合模塊。這將讓你使用的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 
 

的另一件事......如果你在你的寶石的頂級創建默認軌道目錄,你不必擔心需要助手或控制員。您的引擎子類可以訪問它們。所以,我想補充我的應用程序控制器和應用助手擴展這裏:

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

我喜歡這種設置,因爲它類似於在你的Rails應用程序的application_controller和application_helper。同樣,這僅僅是個人喜好,但我儘量保持任何直接軌關係,如控制器,助手和模型內/ my_engine /應用程序,任何在一般的內/ my_engine/lib目錄相關插件

看看本教程由何塞·Valim更多信息有關初始化: https://gist.github.com/e139fa787aa882c0aa9c(引擎名稱現已棄用,但大多數這個文檔似乎跟上時代的)

+0

+1和接受 - 謝謝你這真棒新手必看!我感謝您抽出寶貴,即使我已經回答說:「」我自己的時間。很高興看到更優雅的解決方案。哦,歡迎來到Stack Overflow :-) – 2010-08-16 03:29:56

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中的任何內容,名稱「助手」無關緊要),並將以下內容添加到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