Rails 3.0 Engine - Execute code in ActionController

丶灬走出姿态 提交于 2019-12-03 01:48:22

You may also want to look into the initializers inside your engine subclass, so you don't have to include view helpers inside your controller class. And this will give you control over the load order of these modules.

Here is what I have been using:


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

Also, another option for the action controller extension is using a mixin module. This will let you use the before_filter, after_filter, etc..


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

One other thing... if you create the default rails directories at the top level of your gem, you don't have to worry about requiring the helpers or controllers. Your engine subclass has access to them. So I add my application controller and application helper extensions here:

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

I like this setup because it looks similar to the application_controller and application_helper in your rails app. Again, this is just personal preference, but I try to keep anything that is directly rails related, such as controllers, helpers and models inside /my_engine/app and anything that is related to the plugin in general inside /my_engine/lib

Check out this tutorial by Jose Valim for more info on initializers: https://gist.github.com/e139fa787aa882c0aa9c (engine_name is deprecated now, but most of this doc seems up-to-date)

So, I finally figured out the solution and I hope it helps someone else.

You need to create a file in your lib directory because you are actually going to extend the class. I did myplugin/lib/extensions/action_controller_base.rb.

Then, inside of your myplugin/lib/myplugin.rb file, do the following:

require 'extensions/action_controller_base.rb'

Inside of myplugin/lib/extensions/action_controller_base.rb put the following:

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
}

If you need to have view helpers, create them in the myplugin/lib/helpers directory (or anything inside of lib, the name "helpers" doesn't matter) also and add the following to the bottom of 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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!