aboutsummaryrefslogblamecommitdiffstats
path: root/actionpack/lib/action_controller/abstract/base.rb
blob: 3b85ba5565229568c4350258690f7b0bbee966d0 (plain) (tree)
1
2
3
4
5
6




                                
                              


































                                                                             

       
             
    



                            
                            



                                                                              
                                 
                    



                                                   

         



                               




                                                                       
                      


                                                                                      

       



                                                               
                                       
                                                                                
       

     
module AbstractController
  class Base
    
    attr_internal :response_body
    attr_internal :response_obj
    attr_internal :action_name

    class << self
      attr_reader :abstract    
      
      def abstract!
        @abstract = true
      end
      
      alias_method :abstract?, :abstract
      
      def internal_methods
        controller = self
        controller = controller.superclass until controller.abstract?
        controller.public_instance_methods(true)
      end
      
      def process(action)
        new.process(action)
      end

      def hidden_actions
        []
      end
      
      def action_methods
        @action_methods ||=
          # All public instance methods of this class, including ancestors
          public_instance_methods(true).map { |m| m.to_sym }.to_set -
          # Except for public instance methods of Base and its ancestors
          internal_methods.map { |m| m.to_sym } +
          # Be sure to include shadowed public instance methods of this class
          public_instance_methods(false).map { |m| m.to_sym } -
          # And always exclude explicitly hidden actions
          hidden_actions
      end
    end
    
    abstract!
    
    def initialize
      self.response_obj = {}
    end
    
    def process(action_name)
      unless respond_to_action?(action_name)
        raise ActionNotFound, "The action '#{action_name}' could not be found"
      end
      
      @_action_name = action_name
      process_action
      self.response_obj[:body] = self.response_body
      self
    end
    
  private
  
    def action_methods
      self.class.action_methods
    end
  
    # It is possible for respond_to?(action_name) to be false and
    # respond_to?(:action_missing) to be false if respond_to_action?
    # is overridden in a subclass. For instance, ActionController::Base
    # overrides it to include the case where a template matching the
    # action_name is found.
    def process_action
      if respond_to?(action_name) then send(action_name)
      elsif respond_to?(:action_missing, true) then send(:action_missing, action_name)
      end
    end
    
    # Override this to change the conditions that will raise an
    # ActionNotFound error. If you accept a difference case,
    # you must handle it by also overriding process_action and
    # handling the case.
    def respond_to_action?(action_name)
      action_methods.include?(action_name) || respond_to?(:action_missing, true)
    end
  end
end