剖析简单的 Rails 应用

Rails 使用 index 方法作为默认值,因此在将地址输入浏览器时可以省略 URL 的那一部分:

  1. http://localhost:3000/say_hello

在继续之前,让我们仔细看看我们正在使用的类。Rails 通过将 Controller 附加到我们在运行控制器生成器脚本(HelloWorld)时指定的名称来命名该类,并使它成为 ApplicationController 类的后代:

  1. class SayHelloController < ApplicationController

究竟什么是 ApplicationController 类?现在,你可能还记得我提到我们之前运行的 generate/controller 脚本在 /app/controllers 文件夹中静默创建了一个名为 application.rb 的文件。此文件是应用程序控制器,如果打开它,你将看到它包含一个类名为:

  1. ApplicationController < ActionController::Base

因此,我们的 SayHelloController 类继承自 ApplicationController 类,该类本身继承自 ActionController 模块中的 Base 类。你可以通过遍历层次结构并要求每个类显示自己来证明这一点。

顺便说一句,这也让我们有机会尝试在 SayHelloController 类中进行一些真正的 Ruby 编程。

只需编辑 say_hello_controller.rb 文件的内容以匹配以下内容(或者复制并粘贴本章代码存档中的 sayhello1.rb 文件中的代码):

sayhello1.rb
  1. class SayHelloController < ApplicationController
  2. def showFamily( aClass, msg )
  3. if (aClass != nil) then
  4. msg += "<br />#{aClass}"
  5. showFamily( aClass.superclass, msg )
  6. else
  7. render :text => msg
  8. end
  9. end
  10. def index
  11. showFamily( self.class, "Class Hierarchy of self..." )
  12. end
  13. end

要查看结果,请在浏览器中输入此地址(如果需要,请再次更改端口号):

  1. http://localhost:3000/say_hello/

你的 Web 浏览器现在应该显示…

  1. Class Hierarchy of self...
  2. SayHelloController
  3. ApplicationController
  4. ActionController::Base
  5. Object

如你所见,Rails 控制器文件包含 Ruby 代码。你可以在控制器中使用所有常用的 Ruby 类,例如 String 和 Hash,你可以调用方法并传递参数。

但请记住,最终结果需要显示在网页中。这有一定的后果。例如,不要将换行符 “\n” 放入字符串中,而应使用 HTML 段落,<P> 或换行 <br/> 标记,并且每次显示页面时只允许调用 render 一次,这就解释了为什么我在递归调用方法的过程中构造了一个字符串,然后将其传递给最后的 render 方法:

  1. def showFamily( aClass, msg )
  2. if (aClass != nil) then
  3. msg += "<br />#{aClass}"
  4. showFamily( aClass.superclass, msg )
  5. else
  6. render :text => msg
  7. end
  8. end

生成控制器脚本摘要

让我们简要回顾一下当我们运行 generate controller 脚本时发生的事情。每次生成一个新控制器时,它都会在 app/controllers 目录中创建一个 Ruby 代码文件,其名称与你输入的名称相匹配,但全部为小写,并且你指定的任何非初始大写字母前面都加了下划线并且最后附加 _controller。因此,如果你输入 SayHello,则控制器文件将被命名为 say_hello_controller.rb 。控制器将包含一个类定义,例如:SayHelloController。你还可以通过在执行脚本时包含这些视图名称来指定“视图”,例如 indexbye … ruby script/generate controller SayHello index bye在这种情况下,Controller 类将自动提供名称与这些视图匹配的方法(def indexdef bye)。无论如何,无论你是否指定视图,都会在 /views 目录中创建一个的文件,其名称与控制器匹配(views/say_hello)。实际上,该脚本还会创建一些其它文件,包括 /helpers 文件夹中的一些更多 Ruby 文件,但我们现在可以忽略它们。如果在运行控制器脚本时指定了视图名称,则某些名称匹配且扩展名为 .html.erb 的文件将添加到相应的视图文件夹中。例如,如果你输入了命令… ruby script/generate controller SayHello xxx…/views/say_hello 目录现在应该包含一个名为 xxx.html.erb 的文件。另一方面,如果你输入了… ruby script/generate controller Blather xxx bye snibbit…views/blather 目录现在应该包含三个文件:xxx.html.erb, bye.html.erbsnibbit.html.erb