How can I extend ApplicationController in a gem?

后端 未结 4 965
小鲜肉
小鲜肉 2020-12-15 20:32

I thought I\'d come up with a slick way to extend ApplicationController in a Rails 3.x gem.

In my gem\'s lib/my_namespace/my_controller.rb, I had:

相关标签:
4条回答
  • 2020-12-15 21:08

    I was able to reference ApplicationController with an initializer callback.

    gem code that subclasses/references ApplicationController:

    class GemApplicationController < ApplicationController
      before_filter :method_to_call
    
      def method_to_call
        #your code here
      end
    end
    

    gem code callback to create subclassed controller:

    module GemName
      def self.load_gem_application_controller
        require "path/to/gem_application_controller"
      end
    end
    

    rails_app/config/initializers/gem_name.rb

    GemName.load_gem_application_controller
    

    Then have controllers that use this functionality subclass GemApplicationController

    class SpecialCaseController < GemApplicationController
      # this will inherit from the gem's controller, 
      # which inherits from the rails_app ApplicationController
    end
    
    0 讨论(0)
  • 2020-12-15 21:16

    Here is a Gist that shows how to access the class of the subclass and store it in an instance variable and access it in the before and after filters. It uses the include method.

    0 讨论(0)
  • 2020-12-15 21:18

    For this specific kind of functionality I would recommend creating a module in your gem and include that module in your Application Controller

    class ApplicationController < ActionController::Base
      include MyCoolModule
    end
    

    To add before filters, etc (add this to your module)

    def self.included(base)
      base.send(:before_filter, my_method)
    end
    

    Update: you may be able to just do base.before_filter :my_method which is cleaner.

    0 讨论(0)
  • 2020-12-15 21:21

    Truth is much much simpler and flexible.

    Add to lib/engine.rb this: class Engine < Rails::Engine; end

    And then simply use:

    ActionController::Base.class_eval do
    
      include SomethingFromMineGemModule
    
      # or:
      def hello_from_gem
        'Hey people!'
      end
    
    end
    
    0 讨论(0)
提交回复
热议问题