`
fantaxy025025
  • 浏览: 1250174 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

Rails源码阅读(七)ActionController::Dispatcher_用户请求在rails中的处理流程(2)

 
阅读更多

Rails源码阅读(七)ActionController::Routing::Routes_用户请求在rails中的处理流程(2)

 

ActionController::Dispatcher把主要工作交给了ActionController::Routing::Routes.call(@env)

ActionController::Routing::Routes的代码:

Routes = RouteSet.new

原来这个常量不是个module,也不是class,是个实例

这样call方法就是RouteSet.new的call方法了

 

RouteSet的call代码:

      def call(env)
        request = Request.new(env) #a new一个request真简单!
        app = Routing::Routes.recognize(request) #b 识别Controller 下面详细说
        app.call(env).to_a #调用call,返回的结果to_a,一定是rack的标准输出了
      end

 

Routing::Routes.recognize(request)做了什么:

      def recognize(request)
        params = recognize_path(request.path, extract_request_environment(request))
        request.path_parameters = params.with_indifferent_access #原来这个东西在这里做的!实际使用发现,一不小心,很难调试的bug就会从这里出来阿!!!
        "#{params[:controller].to_s.camelize}Controller".constantize
      end

查看返回结果,函数返回了要访问的Controller。

至此,终于接触到达了我们写的代码:XXXController处。

这样app就是某个我们自己写的Controller了,注意这是个类,不是个实例!

 

从app.call(env).to_a来看,每个Controller都有个call(env)方法,所以应该在父类里。看看继承结构:

XXXController < ApplicationController < ActionController::Base

果然是从super-class来的,否则自己写多麻烦:

ActionController::Base.call方法(注意这里是类方法!):
    class << self
      def call(env)
        # HACK: For global rescue to have access to the original request and response
        request = env["action_controller.rescue.request"] ||= Request.new(env)
        response = env["action_controller.rescue.response"] ||= Response.new
        process(request, response) #这里!
      end
      # ActionController::Base.process代码:
      # Factory for the standard create, process loop where the controller is discarded after processing.
      def process(request, response) #:nodoc:
        new.process(request, response)
      end
    end

 

 

 

总结:

#1 RouteSet的call方法,根据访问链接和路由配置,识别出了应该去找哪个XXXController,同时找哪个action也得到了,放入params:

Parameters: {"method"=>:get, "action"=>"follow", "controller"=>"profile"}

#2 执行XXXController.run方法

到这里,执行流程到了:ActionController::Base,即:ActionController::Base.process方法。

 

 

 

====结束====

===           ===

==                ==

=                     =

|                       |

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics