`
pingfeng
  • 浏览: 59338 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

rails 原码分析,理顺则好用

阅读更多
一直专业写rails程序,很多东西也没有理清,不通则不快。趁过年前有时间,剖析一下!系统化程度越高,构建才会快,质量高。开始:

动机: 一直不太明白ActiveController和ActiveView的关系,即两者的上下文关系。

对老系统的Rails 2.1.2 剖析,3.0.0改动太大了,下次再仔细研究。

1.  从CGI 的dispatch  一路dispatch过来,到AC(ActiveController)

def handle_request
        @controller = Routing::Routes.recognize(@request)
        @controller.process(@request, @response).out(@output)
      end

从url中把路由取出来,很自然,找到对应的controller,如HomeController,但还不是实例,类型是Class。

2. controller来process

class << self
      # 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

这里的new很有意思,把自己new出来然后出处理。下面几行代码是ruby的模块与类的魔法

module ActionController #:nodoc:
  module SessionManagement #:nodoc:
    def self.included(base)
      base.class_eval do
        extend ClassMethods
        alias_method_chain :process, :session_management_support
        alias_method_chain :process_cleanup, :session_management_support
      end
    end

include(base)。 再向base注入Module方法:seesion_mangement_support

上面把session的管理option放入request

3. 进入Filter Module的before_filter

   def process_with_filters(request, response, method = :perform_action, *arguments) #:nodoc:
          @before_filter_chain_aborted = false
          process_without_filters(request, response, method, *arguments)
        end

基本上rails的一个特性就有一个Module对应,这里就是filter这个module

4.  关键:进入AR::Base的process

   def process(request, response, method = :perform_action, *arguments) #:nodoc:
        initialize_template_class(response)
        assign_shortcuts(request, response)
        initialize_current_url
        assign_names
        forget_variables_added_to_assigns

        log_processing
        send(method, *arguments)

        assign_default_content_type_and_charset

        response.request = request
        response.prepare! unless component_request?
        response
      ensure
        process_cleanup
      end

initialize_template_class(response) 非常关键把 AV(ActiveView)new出来了,开始了AC与AV的关系!这个view名字为template

assign_shortcuts(request, response)
        initialize_current_url
        assign_names
        forget_variables_added_to_assigns
都是内部变量记录,无实质性内容!

5.   send(method, *arguments) 进入perform_ation

          send(action_name)就进到了客户的HomeController里,动态语言的好处就是不断的send,不用做各种工厂!


  def perform_action
        if self.class.action_methods.include?(action_name)
          send(action_name)
          default_render unless performed?
        elsif respond_to? :method_missing
          method_missing action_name
          default_render unless performed?
        elsif template_exists? && template_public?
          default_render
        else
          raise UnknownAction, "No action responded to #{action_name}", caller
        end
      end

6. 在自己的action里,调用 respond_to

  def respond_to(*types, &block)
        raise ArgumentError, "respond_to takes either types or a block, never both" unless types.any? ^ block
        block ||= lambda { |responder| types.each { |type| responder.send(type) } }
        responder = Responder.new(self)
        block.call(responder)
        responder.respond
      end

之前一直觉得respond_to方法名字和后的block不是很雅,也不知那哪里跑出个这么的妖怪

都是用以下的方法mixin类方法进来的

module MimeResponds #:nodoc:
    def self.included(base)
      base.module_eval do
        include ActionController::MimeResponds::InstanceMethods
      end
    end

    module InstanceMethods

7. 走自己controller的repond_to后面的块

respond_to do |format|
      format.html {render :template=>"home/template"}
    end

有时这个块会写两层,其它很不方便的

respond_to do |format|
    format.js{ render :update do |page|
        page.replace_html "{$1 div_id}", :partial=>"",bject=>@
      end}
  end
 

8. 进入AC的render

   else
          if file = options[:file]
            render_for_file(file, options[:status], options[:use_full_path], options[:locals] || {})

          elsif template = options[:template]
            render_for_file(template, options[:status], true, options[:locals] || {})


9. 关键:进入AV的rend_file
@template.render_file最后new出一个template

在AV里有一个Template
     Template.new(self, template_path, use_full_path, local_assigns).render_template

10. 关键:进入Template的render_template
  module ActionView #:nodoc:
  class Template #:nodoc:


template里有一个handler指是是什么类型的模板,如:ActionView::TemplateHandlers::ERB

def render
      prepare!
      @handler.render(self)
    end

prepare!是一些准备工作,hander里有个compile_template,不是很明白是做什么的。ms是在template做一些求值。接着再转回AR::base

@hander是要Render的类型,是ebd,还是haml。

11. 关键:进入TemplateHandlers的render

         @view.send :execute, template

又回到 AV

def execute(template)
        send(template.method, template.locals) do |*names|
          instance_variable_get "@content_for_#{names.first || 'layout'}"
        end       
      end

就进去我们自己的erb文件了


此时 method 为_run_erb_47app47views47home47template46html46erb

显然,47是/折算过来的,这个方法也不知道是什么时候产生的。

个人觉得很牛,很神,把一个erb文件当ruby文件来跑。

总之呢,动态的把我们的erb文件变成了一个方法,send一下就去到erb文件里做计算<%= %> 输出了。

=========================

总结:

AR与AV的关系好像是管家与工人,前者是一个请求的生开始到最后完成,完成的全过程。

AV则是与render一起,其中两个可定制的地方,一个是不同类型的请求,如js, xml, json可以不同的resonder。AV里一个template,可以不同的hander,如对付erb的,和其它的。

AV生命周期更短一些,是管家的render工人,做完了更早被boss fire掉!

AR和AV都有自己的render,很容易搞混!


分享到:
评论

相关推荐

    Ruby-Rails日志分析器查看您的视图渲染的速度

    本话题主要关注如何使用Ruby编写日志分析器来洞察Rails应用中视图渲染的速度,从而优化整体性能。 首先,日志文件在Ruby on Rails中扮演着至关重要的角色,它们记录了应用程序运行时的详细信息,包括数据库查询、...

    好用的rails 2.0 Api 文档

    Rails 2.0 API 文档是一个非常宝贵的资源,它为开发者提供了全面的指南,以便于在使用Ruby on Rails 2.0版本时更好地理解和利用其框架功能。Ruby on Rails(简称Rails)是一个开源的Web应用框架,它遵循MVC(模型-...

    Rails 101 入门电子书

    ### Rails 101 入门电子书知识点详解 #### 一、简介 《Rails 101 入门电子书》是一本非常适合初学者直接入门的书籍,它由xdite编写并出版于2014年6月10日。本书主要针对的是希望学习Ruby on Rails框架的读者,特别...

    ruby on rails源代码分析

    在本文中,我们将深入分析 Ruby on Rails 2.0.2 的源代码,特别是关注其启动过程。 首先,Rails 的启动始于 `config/boot.rb` 文件。这个文件是 Rails 应用程序的入口点,负责检查 Rails 是否已启动。如果没有,它...

    Rails101_by_rails4.0

    而在Rails开发中,合适的编辑器可以提高代码编写和管理的效率,Linux命令行则对于部署和维护开发环境有着重要作用。 为了确保读者能够通过实践加深理解,书中还安排了一系列练习作业,从最基础的“Hello World”...

    Rails项目源代码

    Ruby on Rails,通常简称为Rails,是一个基于Ruby编程语言的开源Web应用框架,遵循MVC(Model-View-Controller)架构模式。这个“Rails项目源代码”是一个使用Rails构建的图片分享网站的完整源代码,它揭示了如何...

    关于rails 3.1 cucumber-rails 1.2.0

    Asset Pipeline优化了前端资源的处理,Cucumber-Rails则提供了强大的测试工具,确保代码的质量和功能符合业务需求。这样的组合对于保持代码的整洁、提高团队协作效率和降低维护成本具有重要意义。 总的来说,了解和...

    Rails

    标签 "源码" 暗示了可能涉及Rails的源代码分析或自定义扩展。Rails是开源的,开发者可以深入研究其内部机制,理解工作原理,甚至为框架贡献代码。 标签 "工具" 可能意味着讨论到了与Rails开发相关的工具,如集成...

    rails2-sample

    从给定的文件信息来看,我们正在探讨的是一本关于Ruby on Rails的书籍,书名为《Simply Rails2》,作者是Patrick Lenz。本书旨在为初学者提供深入理解Ruby on Rails框架的指南,从基础概念到高级主题均有涵盖,是...

    rails指南 中文版

    5. **Gemfile与Bundler**:Rails项目通常使用Gemfile来管理依赖库,Bundler工具则用于安装和管理这些依赖,确保在不同环境下项目的运行一致性。 6. **Scaffolding**:Rails提供了快速生成基本CRUD(Create, Read, ...

    使用Aptana+Rails开发Rails Web应用(中文)

    在开发Web应用时,Ruby on Rails(简称Rails)框架因其高效、简洁的代码风格和强大的社区支持而备受青睐。Aptana是一款强大的集成开发环境(IDE),尤其适用于Rails项目的开发,它提供了丰富的特性来提升开发效率。...

    Rails recipes

    作者们通过分享自己的经验和见解,为Rails程序员提供了一本既有实际操作指导又有理论深入分析的参考书。 Ruby on Rails是一种流行的开源Web应用框架,用Ruby语言编写,遵循MVC架构模式。Rails的目的是让开发过程尽...

    rails本地安装包完整版

    Rails是Ruby编程语言的一个著名框架,用于开发Web应用程序。它以MVC(模型-视图-控制器)架构模式为基础,提供了许多内置功能,使开发者能够更高效地编写代码。在这个"rails本地安装包完整版"中,包含了Rails 2.1.0...

    Ruby on Rails安装指南(Ruby 1.8.6+Rails 2.0.2)

    Ruby on Rails 安装指南 Ruby on Rails 安装指南是指安装 Ruby 1.8.6 和 Rails 2.0.2 的详细步骤。首先,需要下载 Ruby One-Click Installer 版本,并安装 Ruby。然后,下载 Rails 2.0.2 版本,并安装。接下来,...

    rails敏捷开发的购物车系统

    在本文中,我们将深入探讨如何使用Rails敏捷开发技术构建一个购物车系统,特别是在参考《rails敏捷开发第四版》中的示例。Rails 3.2.6是本文的基础框架,它是一个强大的Ruby Web应用程序框架,以其MVC(模型-视图-...

    Ruby on Rails实例开发

    Ruby on Rails,简称Rails,是基于Ruby编程语言的一个开源Web应用程序框架,它遵循MVC(模型-视图-控制器)架构模式,旨在提高开发效率和可读性,同时强调“约定优于配置”的原则。在本实例开发中,我们将探讨如何...

    rails 项目起步示例

    Rails是Ruby语言的一个著名Web开发框架,全称为Ruby on Rails,它遵循MVC(Model-View-Controller)架构模式,旨在提高开发效率和代码可读性。本示例"rails项目起步示例"是一个购物系统,非常适合初学者入门学习。 ...

    rails 2.3.2离线安装rails 2.3.2离线安装

    rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails 2.3.2离线安装rails ...

    Rails进行敏捷Web开发(所有版本的源码rails3.0-4.0)

    Rails是Ruby语言的一个著名Web应用框架,以敏捷开发和“约定优于配置”...通过对这些版本的源码进行分析和学习,开发者不仅可以提升对Rails框架的理解,还能在实际项目中运用这些知识,编写出更高效、更安全的Web应用。

Global site tag (gtag.js) - Google Analytics