Rails3 入门指南(简体版)
阅读量(3254) | 转载 于 2010-09-15 20:46:04
翻译《Rails 入门指南》之前,首先声明,翻译参考了官方英文版和台湾同胞 Ihower繁体版的细节,肯定有很多没有完善的,还需要读者不啬指正。如果遇到问题,强烈推荐查阅官方原版。当然读者找到遗漏或错误的,希望给龅牙驴回帖。以下是翻译的内容:
这份文件涵盖了如何上手使用Ruby on Rails。 阅读之后您应该可以熟悉:
- 安装Rails,建立一个新的Rails 应用程序,并使用到数据库
- Rails 的架构
- MVC (Model, View Controller)基本原理以及RESTful设计
- 如何快速产生可以运行的Rails 应用程序
这份文件基于Rails 3.0。 某些代码无法运行于旧版Rails。
1 前提条件
这份指南的目标是为了帮助初学者从头开始学习Rails 应用程序,而不需要有任何Rails 经验。 不过要能够读的懂,还是需要一些前提:
Ruby程序语言版本
Ruby 1.8.7 p248 和p249 已知有marshaling 臭虫会搞烂Rails 3.0。 而Ruby Enterprise Edition需要
RubyGems Ruby的套件管理系统
SQLite3数据库
Rails 是一套使用Ruby 的Web 框架。 如果您对Ruby 一无所知就一头栽进Rails,您的学习曲线会非常陡峭。 以下是一些网路上的免费Ruby 学习资源:
2 什么是Rails?
Rails 是个使用Ruby 程序语言开发的网站开发架构。 它的是设计目标是只要开发者熟悉它的惯例,它就可以让网站开发变的非常容易。 而相对于其他程序语言和框架,Rails 可以让你用更少的代码达成更多的功能。 经验丰富的Rails 开发者也表示它让网站开发更有趣了。
Rails 也是个很有主见(opinionated)的软件。 意思是说它假定事情有"最佳解",而且它也被设计成鼓励那么做– 而不鼓励其他作法。 如果你学会所谓的“The Rails Way” 的话,你的生产力非常可能获得极大的增长。 但如果你硬套用其他语言的习惯或模式来使用Rails,你可能会有不愉快的使用经验。
Rails 的哲学包括以下指导原则:
- DRY – “不要重复自己(Don't Repeat Yourself)” –撰写出重复的代码是件坏事
惯例胜于设计(Convention Over Configuration) – Rails 会假设什么是你要做的事情跟如何去做,而不是要求你设定每一个细节到配置文档中。
- REST是Web应用程序的最佳模式–使用Resources和标准的HTTP verbs(动词)来组织你的应用程序是最快的方式
2.1 MVC架构
Rails 的核心是Model, View 和Controller 的架构,通常称作MVC。 MVC 的好处包括:
从使用者接口中把商业逻辑隔离出来
更容易使程序保持DRY
容易维护,让不同的代码干净地放在属于它的地方
Model 代表了应用程序的数据和操作数据的逻辑。 在Rails 中,Models 主要的功能是负责操作数据库表。 在大多数的情况,一个数据库表就对应了一个Model。 你的应用程序商业逻辑也会放在Models 中。
Views 代表了应用程序的使用者接口。 在Rails中,Views通常就是有内嵌Ruby程序(可以操纵如何显示数据)的HTML文件。 Views负责提供数据给浏览器或其他发HTTP请求的软件。
Controllers 是Models 和Views 之间的黏着剂。 在Rails中,Controllers负责处理从浏览器进来的HTTP请求,并对Models询问数据,然后将数据传进Views中显示出来。
2.2 Rails 元件
Rails 包含许多个别的元件:
- Action Pack
- -- Action Controller
- -- Action Dispatch
- -- Action View
- Action Mailer
- Active Model
- Active Record
- Active Resource
- Active Support
- Railties
Action Pack 是个包含Action Controller、Action View 和Action Dispatch 的gem。 也就是“ MVC ”中的“VC”部分。
Action Controller 是Rails 应用程序中,管理Controllers 的元件。 Action Controller框架处理传给Rails的HTTP请求,取出参数,然后分派给所属的Action。 Action Controller 还提供了session 管理、模板渲染(template rendering) 和redirect 功能。
Action View 负责Rails 应用程序中的Views。 它预设可以产生HTML或XML输出。 Action View 负责模板的渲染(template rendering),包括嵌套(nesting)或局部(partial)模板,甚至也内建支援一些Ajax。
Action Dispatch处理HTTP请求的路由(routing),它把HTTP请求发派(dispatch)到它该去的地方,也许是你的应用程序或其他Rack程序。
Action Mailer 是个建构E-mail 功能的框架。 你可以使用Action Mailer 来接收来信,或是使用模板来寄出纯文字或复杂的multipart 信件。
Active Model在Action Pack gem和ORM gem (例如Active Record)之间定义了一组接口。 Active Model允许Rails可以依你的需求把Active Record换成其他ORM框架。
Active Record 是Rails 应用程序中的Models 基础。 它不依存特定的数据库系统,提供了CRUD功能、先进的查询能力以及可以跟其他Models关联的本事。
Active Resource 提供了与其他商业对象和RESTful 网路服务的链接框架。 它实作了一种可以对应以Web为基础的Resources成为本地端支援CRUD的对象。
Active Support 是Rails 里的工具类库,它也扩充了一些Ruby 标准类库。 除了被用在Rails 核心程序中,你也可以在你的程序中使用。
Railties 是Rails 的核心代码,用来把以上各种的框架类库以及Plugin 全部组合在一起。
2.3 REST
REST代表了“Representational State Transfer” (表象化状态转变),它也是RESTful架构的基础概念。 它被认为出自于Roy Fielding的博士论文Architectural Styles and the Design of Network-based Software Architectures 。 当你阅读这篇论文的时候,REST 被Rails 浓缩成两个主要定理:
使用Resource 来当作识别资源,也就是使用URLs 来代表Resources
Transferring representations of the state of that
resource between system components (译注:????)
例如,对Rails应用程序来说,这样的HTTP请求:
DELETE /photos/17
被解析为指向photo resource 的ID 17,并带着一个动作– 删除这个resource。 REST 对Web 应用程序来说是一种天生的设计风格,而Rails 帮你把这个概念包装实作出来,并且免于众多繁杂RESTful 理论及浏览器怪癖之苦。
如果你想知道更多关于REST架构风格,以下资源比起Fielding的论文更容易亲近:
- A Brief Introduction to REST by Stefan Tilkov
- An Introduction to REST (video tutorial) by Joe Gregorio
- Representational State Transfer article in Wikipedia
- How to GET a Cup of Coffee by Jim Webber, Savas
Parastatidis & Ian Robinson
译注: 什么是REST跟RESTful? (了解REST理论并不是在Rails中使用RESTful技术的前提,所以大可以跳过不甚理解没关系。)
3 建立新的Rails
案例
接下来的范例,你将建立一个叫做blog的Rails案例,是个非常简单的博客系统。
在你开始建构这个应用之前,需要确认你的Rails 已经安装妥当。
3.1 安装Rails
大多数的情况,最简单的安装方式是通过Rubygems:
通常会用root user 来执行: $ gem install
rails
目前还是Rails
如果你使用Windows,你可以安装看看Instant Rails
,不过要注意它的Rails版本比较旧不兼容。 另外你也会发现Rails
跑在Windows 很慢。 所以可能的话,我们建议你装在Linux
虚拟机器上跑Rails,而不是Windows。 (译注:建议使用RubyInstall安装Ruby
龅牙驴注:windows下安装rails3 请参考 Windows下配置Rails3开发环境
3.2 建立博客应用程序
本指南的最佳学习方式就是紧跟着接下来的每个步骤。 没有任何步骤或程序会被省略,所以你可以一步步跟着。 如果你需要下载完整的程序,可以从这里下载Getting Started Code 。
要开始了,首先打开终端(terminal),然后找个适合放你程序的目录,接着输入:
$ rails new blog
这会建立一个叫做Blog 的Rails 应用程序在blog 目录下。
你可以通过rails -h的指令看到所有可用的指令
完成之后,进到这个目录下继续:
$ cd blog
总之,Rails会建立一个工作目录叫做blog 。 请打开这个目录看看它的内容。
本指南的大部分工作都会发生在app目录下,这里来简单走访一下各个目录的功能吧:
文件/目录 目录
- Gemfile 设定你的Rails 应用程序会使用哪些Gems
- README .rdoc 你的应用程序使用手册。 你可以用来告诉其他人你的应用程序是做什么用的,如何使用等等。
- Rakefile 用来载入可以被指令执行的一些任务
- app/ 包含了Controllers、Models
和Views,接下来的指南内容主要都在这个目录。
- config/ 应用程序配置文档、路由规则、数据库设定等等
- config.ru 用来启动应用程序的Rack 配置文档
- db/ 目前数据库的Schema(纲要)
和数据库Migrations,我们很快就会学到什么是Migrations
- doc/ 用来放你的文件
- lib/ 扩充用的Modules 文件(不在本指南范围)
- log/ 应用程序的log 文件
- public/ 唯一可以在网路上看到的目录,这是你的图档、javascript、stylesheets ( CSS )和其他静态文件摆放的地方
- script/ 包括了让你开始Rails 案例的script
以及其他script
- test/ 单元测试、fixtures及其他测试程序,我们在Testing Rails Applications一文中会介绍
- tmp/ 暂时性的文件
- vendor/ 用来放第三方代码的地方。 例如Ruby Gems、Rails 原出处(如果你要装在你的案例里面) 和可以增加功能的Plugin(插件)
3.3 安装必要的Gems
Rails使用Bundler gem来管理所有你应用程序会依存的gems到vendor目录。 到目前为止,我们根据预设不需要特殊的gem,我们只需要执行以下指令就可以准备好了:
$ bundle install
3.4 设定数据库
几乎每一个Rails 应用程序都会与数据库互动。 而数据库需要一个配置文档是config/database.yml 。 如果你打开这个文件,你会发现预设设定是SQLite3。 这个文件包含三个不同的部分,对应到三个Rails 预设环境:
development environment开发模式,用在你的开发的时候
test environment测试模式,用在自动测试时
production environment正式上线模式,用在实际的上线运行环境
Rails预设内建支援SQLite3这是一套非常轻量的非服务器型数据库程序。 虽然繁重的上线环境可能超过SQLite 的负担,但是它却非常适合开发和测试时使用。 Rails 预设使用SQLite 数据库来建立新的案例,当然你也可以换别的数据库。
这里是一段有连线数据的开发用预设配置文档( config/database.yml ):
development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000
本指南使用SQLite3 数据库,因为它完全不需要什么设定就可以用了。 Rails 当然也支援MySQL 跟PostgreSQL,也有其他数据库系统的plugins。 如果是正式的上线环境就会需要了。
如果你选择使用MySQL取代预设的Sqlite3数据库,你的config/database.yml会有点不同,以下是一个开发用的配置文档:
development:
adapter: mysql2
encoding: utf8
database: blog_development
pool: 5
username: root
password:
socket: /tmp/mysql.sock
如果在你的开发用电脑MySQL 有使用者root 和空白密码,那这个设定就可以直接用了。
不然,请修改username 和password。
最后,如果你选择使用PostgreSQL,你的config/database.yml可以设定成:
development:
adapter: postgresql
encoding: unicode
database: blog_development
pool: 5
username: blog
password:
变更username 和password 以符合你所需。
3.5 建立数据库
现在你的数据库设定妥当,是时候让Rails 建立空的数据库了。 输入以下的rake 指令:
$ rake db:create
这会在db/目录下建立development和test的SQLite3数据库。
Rake是个在Rails中广泛运用的通用型command指令工具,你可以输入rake -T列出所有可用的指令。
4 Hello,Rails!
每学习一个新的程序语言,一开始都会有个输出Hello, World! 的最简单练习。 为了办到这件事情,你需要启动Rails 应用程序的服务器。
4.1 启动Web
服务器
其实你已经有了可以运行的Rails 应用程序了。 要在你的开发机器上启动Web 服务器,请输入:
$ rails server
这会启动一个Mongrel (译注:或是WEBrick) 服务器(Rails 也可以用其他的服务器)。 要看到结果,请打开浏览器前往http://localhost:3000 。 你应该就会看到Rails 的预设首页。

要关闭服务器的话,请输入Ctrl+C。 在development mode 开发模式的话,Rails 通常是不需要重新启动的,修改的文件会自动载入。 (译注:如果是production mode 的话,修改任何文件都必须重新启动服务器才会有效果)
这个“Welcome Aboard”的画面是Rails应用程序的烟雾测试(smoke test) :它确认了你的软件设定正确。 你可以点击About your application's environment的超链接看到应用程序的环境信息摘要。
4.2 说"Hello",Rails
要让Rails 说"Hello",你必须至少建立一个Controller 跟View。 而我们用一个指令就可以办到了。 在终端输入:
$ rails generate controller home index
如果你在Windows上,或你的Ruby不像常见的设定,你可能需要改成输入ruby \path\to\rails controller home index 。
Rails会新增几个文件,包括app/views/home/index.html.erb 。 这个模板(template)会被home controller里的index action (即index method函数)拿来显示给浏览器。 用编辑器打开这个文件,加入以下代码:
h1>Hello, Rails!</h1>
4.3 设定首页
那现在我们有了Controller 跟View,我们需要告诉Rails 什么时候“Hello Rails” 要出现。 在这个例子里,我们希望把刚刚首页的http://localhost:3000的“Welcome Aboard”换掉,改成“Hello Rails”
第一步是删除预设的首页文件:
$ rm public/index.html
这是因为Rails会优先回传任何public下有的静态文件,而不是Controllers里面建立的动态内容。
接着,你必须要告诉Rails 你真正的首页在哪里。 用编辑器打开config/routes.rb这个文件。 这是你的应用程序的路由文件(routing file) ,它是个特殊的DSL (domain-specific language专属领域语言)告诉Rails如何将进来的HTTP请求派送到Controllers跟Actions。 这个文件包含许多注解起来的范例,其中一行开头是:root to请把注解移掉如下:
Blog::Application.routes.draw do
# You can have the root of your site routed with "root"
# just remember to delete public/index.html.
root :to => "home#index"
root :to => "home#index"这一行告诉Rails将root网址对应到home controller的index action。
接下来用浏览器打开http://localhost:3000 ,你就会看到Hello, Rails!了。
关于更多路由的信息,请参考Rails Routing from the Outside In .
5 使用手脚架(scaffolding) 快速上手
Rails的手脚架(scaffolding)功能可以用一行指令就快速为Resource建立一组Model, Views跟Controller代码。
6 建立Resource
在这个blog 的例子,你可以用手脚架建立Post resource:这将完成博客文章管理功能。 要办到这件事情,在终端输入:
$ rails generate scaffold Post name:string title:string
content:text
虽然手脚架(scaffolding)可以帮助你快速上手,但是可没办法产生出完美符合需求的代码。 因此许多有经验的Rails 开发者根本不用手脚架(scaffolding)功能,而偏好从头打造起Models, Controllers 和Views。
手脚架(scaffold)生成器(generator)会建立出15 个文件在不同目录,以下是个简单的说明:
文件 目的
- db/migrate/20100207214725_create_posts.rb.rb 用来建立posts 据库表的Migration (你的文件开头名称会有不同的timestamp)
- app/models/post.rb Post model
- test/fixtures/posts.yml 用来测试的假文章数据
- app/controllers/posts_controller.rb Posts controller
- app/views/posts/index.html.erb 用来显示所有文章的index 页面
- app/views/posts/edit.html.erb 用来编辑文章的页面
- app/views/posts/show.html.erb 用来显示特定一篇文章的页面
- app/views/posts/new.html.erb 用来新增文章的页面
- app/views/posts/_form.html.erb 用来显示编辑和新增文章的表单partial
- app/helpers/posts_helper.rb 可在文章views 中使用的Helper
函数
- test/unit/post_test.rb posts model 的单元测试
- test/functional/posts_controller_test.rb posts controller 的功能测试
- test/unit/helpers/posts_helper_test.rb posts helper 的单元测试
- config/routes.rb 设定URL路由规则的文件
- public/stylesheets/scaffold.css CSS样式文件
6.1 执行Migration
rails generate scaffold产生出来的程序中,有一项是数据库迁移(database migration) 。 Migration 是种Ruby 类别用来方便建立和修改据库表。 Rails 使用rake 指令来执行migrations,而且它也支援可以逆推migration 步骤。 Migration 的文件名包含了timestamp (时间戳),用来确保它们可以依照建立时间依序执行。
如果你仔细看看db/migrate/20100207214725_create_posts.rb这个文件(记住,你的文件名开头会有点不一样),你会看到:
class CreatePosts < ActiveRecord::Migration
def self.up
create_table :posts do |t|
t.string :name
t.string :title
t.text :content
t.timestamps
end
end
def self.down
drop_table :posts
end
end
以上的Migration有两个函数, up会在migration进数据库时执行,而down则会在之后需要逆推的时候执行。 在这个例子中up会建立posts数据库表,包含两个string栏位和一个text栏位。 它也会建立两个timestamp 栏位(译注: t.timestamps 该行等同于t.datetime :created_at 和t.datetime :updated_at)用来追踪建立和最后修改时间。 更多的Rails migrations信息请参考Rails Database Migrations 。
这时你可以用以下的rake 指令执行Migration:
$ rake db:migrate
Rails 就会执行这个migration 命令,然后告诉你它建立了Posts 数据库表。
== CreatePosts: migrating ====================================================
-- create_table(:posts) -> 0.0019s == CreatePosts: migrated (0.0020s)
===========================================
因为预设是跑在development模式,这个指令会用config/database.yml设定里的development那段所指定的数据库。
6.2 增加超链接
为了能把文章列表加到我们已经建好的首页,你可以放个超链接在首页上。 打开app/views/home/index.html.erb修改成:
<h1>Hello, Rails!</h1> <%= link_to
"My Blog", posts_path %>
这个link_to函数是Rails内建的view helpers (View的辅助函数)。 它会建立一个文字超链接,连到文章列表。
6.3 在浏览器中操作文章
好,你已经准备好可以进入文章列表了,请浏览http://localhost:3000然后点击“My Blog”链接:
这就是Rails执行index view文章页面的结果。 目前数据库里面还没有任何文章,如果你点选New Post超链接,就可以新增一篇文章。 有了文章之后,你就可以编辑、详细浏览或删除。 所有的逻辑和HTML都被内建的rails generate scaffold指令搞定了。
在development模式中(也就是目前的预设环境),Rails每次浏览器来HTTP请求都会重新载入程序,所以不需要重新启动服务器。
恭喜啦,你正在驾驭Rails! 现在让我们看看到底它是如何运行的。
6.4 Model
app/models/post.rb就是Model文件,它非常简单:
class Post < ActiveRecord::Base
end
代码不多,但是注意Post类别继承了ActiveRecord::Base 。 Active Record让你的Model有非常多功能,包括基本的数据库CRUD操作(Create, Read, Update, Destroy,新增、浏览、更新、删除)、数据验证(data validation)、厉害的搜寻以及可以和其他Models 关联在一起。
6.5 新增一些Validation
(验证)
Rails提供一些函数帮助你验证数据的正确性,编辑app/models/post.rb这个文件:
class Post < ActiveRecord::Base
validates :name, :presence => true
validates :title, :presence => true,
:length => { :minimum => 5 }
end
这几行程序会确保所有储存的文章一定会有name 和title 的数据,而且title 至少有五个字节长度。 Rails 提供各种验证的方法,包括必填、唯一性、格式或是需要有关联对象。
6.6 使用Console
控制台
要看到validations 的作用,你可以使用console。 console 是一种指令工具可以让你在Rails 中的环境中执行Ruby 程序:
$ rails console
在console 载入之后,你就可以在里面使用Models:
>> p = Post.new(:content => "A new post")
=> #<Post id: nil, name: nil, title: nil,
content: "A new post", created_at: nil,
updated_at: nil>
>> p.save
=> false
>> p.errors
=> #<OrderedHash { :title=>["can't be blank",
"is too short (minimum is 5 characters)"],
:name=>["can't be blank"] }>
这段程序先建立了一个Post实例,试图要储存进数据库,但是却回传false (表示储存失败),然后观察文章的errors 。
当你完成之后,输入exit按下enter来离开控制台(Console)。
不像在development 模式,console 不会自动载入刚修改的程序。 如果你在console开启之后才修改程序,请输入reload!重新载入。
6.7 列出所有文章
最容易开始上手的地方就是列出文章的代码了。 请打开app/controllers/posts_controller.rb这个文件,然后看看 index+这个action:
def index
@posts = Post.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @posts }
end
end
Post.all会调用Post model回传数据库里所有的文章,结果会是一个包含文章的@posts列表。
关于更多Active Reocrd数据查询的功能,请查阅Active Record Query Interface .
这个respond_to block (代码块)同时处理了HTML和XML请求。 如果浏览器浏览http://localhost:3000/posts.xml你就会看到XML格式。 HTML格式则会去找app/views/posts/下符合action名称的文件。 Rails 会让所有action 里的实例变量(instance variables)(译注: 也就是有@ 开头的变量) 通通传到View 里面可以使用。 以下是app/views/posts/index.html.erb :
<h1>Listing posts</h1>
<table>
<tr>
<th>Name</th>
<th>Title</th>
<th>Content</th>
<th></th>
<th></th>
<th></th>
</tr>
<% @posts.each do |post| %>
<tr>
<td><%= post.name %></td>
<td><%= post.title %></td>
<td><%= post.content %></td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New post', new_post_path %>
这个view迭代了@posts列表并显示内容跟超链接,有几件值得注意的事情:
link_to会建立超链接到特定的位置
edit_post_path和new_post_path都是Rails RESTful路由提供的helpers。 你也会在controller 的不同actions 中看到这些helpers。
在之前的Rails版本,你必须使用<%=h post.name %>如此HTML才会被逸出(译注:可以防止XSS网路攻击)。 在Raisl 3.0 中预设就会逸出。 如果不要逸出,请使用<%= raw post.name %> 。
关于更多rendering的处理,请参阅Layouts and Rendering in Rails .
6.8 自定义Layout
版式
View只是Rails处理HTML的一个环节,还有一项概念叫做layouts ,可以用来包裹views。 当Rails要显示一个view给浏览器时,它会将view的HTML放到layout的HTML里面去。 在之前的Rails版本, rails generate scaffold指令会自动为每个controller建立一个layout,例如app/views/layouts/posts.html.erb就是给posts controller的。 但是在Rails 3.0的scaffold改了,所有的controllers共用一个layout文件叫做app/views/layouts/application.html.erb 。 打开这个文件然后修改它的body标签:
<!DOCTYPE html>
<html>
<head>
<title>Blog</title>
<%= stylesheet_link_tag :all %>
<%= javascript_include_tag :defaults %>
<%= csrf_meta_tag %>
</head>
<body style="background: #EEEEEE;">
<%= yield %>
</body>
</html>
浏览器重新整理/posts页面,你会看到灰色的背景。 同样的背景也会出现在所有的文章views。
6.9 建立新文章
建立一篇新的文章需要两个actions。 第一个是new action,它用来实例化一个空的Post对象:
def new
@post = Post.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @post }
end
end
这个new.html.erb view会显示空的Post给使用者:
<h1>New post</h1>
<%= render 'form' %>
<%= link_to 'Back', posts_path %>
其中<%= render 'form' %>是你第一次遇到partials 。 partial是一个包含HTML和Ruby程序的片段,可以在其他地方重复使用。 在这个例子中,表单被用在新增文章,基本上跟编辑文章的表单相同,两者都有相同的name 跟title 文字栏位跟content 文字区块栏位,以及提交按钮。
如果看清楚views/posts/_form.html.erb这个文件,内容如下:
<%= form_for(@post) do |f| %>
<% if @post.errors.any? %>
<div id="errorExplanation">
<h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% @post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :title %><br />
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :content %><br />
<%= f.text_area :content %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
这个partial 接收了来自view 的所有的实例变量(instance variables)。 在这个例子中,controller 中设定了@post 是新的Post 对象,所以在view 跟这个partial 中也都有这个@post 对象。
想知道更多partials的信息,请参阅Layouts and Rendering in Rails 。
这个form_for block (代码块)被用来建立HTML表单。 在block 之中,你可以使用各种函数来建构表单。 例如f.text_field :name建立出一个文字输入框,并填入@post的name属性数据。 但这个表单只能基于这个model有的属性(在这个例子是name 、 title跟content )。 Rails偏好使用form_for而不是让你手写表单HTML,这是因为代码可以更加简洁,而且可以明确地绑在一个model实例上。
form_for block也非常聪明,不同的New Post跟Edit Post表单action属性跟提交按钮的文字也会跟着不同(译注:根据@post的不同,前者是全新的,后者是已经建立过的)。
如果你需要建立任意栏位的HTML表单,而不绑在某一个model上,你可以使用form_tag函数。 它也提供了建构表单的函数而不需要绑在model 实例上。
当使用者点击表单的Create Post按钮时,浏览器就会提交数据到controller的create函数(Rails会知道要调用create函数,这是因为表单是用HTTP POST请求的,这是个稍早提过的RESTful 惯例):
def create
@post = Post.new(params[:post])
respond_to do |format|
if @post.save
format.html { redirect_to(@post,
:notice => 'Post was successfully created.') }
format.xml { render :xml => @post,
:status => :created, :location => @post }
else
format.html { render :action => "new" }
format.xml { render :xml => @post.errors,
:status => :unprocessable_entity }
end
end
end
create action会通过从表单传进来的数据,也就是Rails提供的params hash哈希,来实例化一个新的Post对象。 成功储存之后, create会根据使用者的请求回传适当的格式(在这个例子是HTML )。 这里它是把使用者指向(redirect)到show action显示文章内容,并设定notice提醒使用者Post已经成功被建立。
如果文章因为validation错误而储存失败,这里会回传给使用者带有错误信息的new action,好让使用者可以修正问题再试一次。 (译注: render :action => "new"会回传new action使用的模板,而不是执行new action这个函数。如果改成使用redirect_to new_post_path则会让浏览器重新发送请求到new action,但是如此一来@post 就被重新建立而失去使用者刚输入的数据)
“Post was successfully created”的信息会被储存在Rails的flash hash里(通常就称作Flash)好让信息可以被带到另一个action,它可以提供使用者一些有用的信息。 在这个create的action中,使用者并没有真的看到任何页面,因为它马上就被指向到新的文章页面。 而这个Flash就带着信息到下一个action,好让使用者在show action页面看到“Post was successfully created.”这个信息。
6.10 显示个别文章
当你在index页面点击show的文章链接,就会前往如http://localhost:3000/posts/1的网址。 Rails会针对这个resource去调用show action,然后传进1到id参数。 以下是show action。
def show
@post = Post.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @post }
end
end
这个show action根据id值使用Post.find从数据库中找出该篇文章。 找到数据之后,Rails用show.html.erb显示出来:
<p class="notice"><%= notice %></p>
<p>
<b>Name:</b>
<%= @post.name %>
</p>
<p>
<b>Title:</b>
<%= @post.title %>
</p>
<p>
<b>Content:</b>
<%= @post.content %>
</p>
<%= link_to 'Edit', edit_post_path(@post) %> |
<%= link_to 'Back', posts_path %>
6.11 编辑文章
如同建立新文章,编辑文章也有两个步骤。 第一个是请求特定一篇文章的edit_post_path(@post)页面。 这会调用controller的 edit+ action:
def edit
@post = Post.find(params[:id])
end
找到要编辑的文章之后,Rails显示edit.html.erb页面:
<h1>Editing post</h1>
<%= render 'form' %>
<%= link_to 'Show', @post %> |
<%= link_to 'Back', posts_path %>
<% end %>
这里也像new action, edit action使用form partial,只是这一次表单会用HTTP PUT动作给PostsController,而且提交按钮的字样变成“Update Post”。
提交表单后,会调用controller的update action:
def update
@post = Post.find(params[:id])
respond_to do |format|
if @post.update_attributes(params[:post])
format.html { redirect_to(@post,
:notice => 'Post was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @post.errors,
:status => :unprocessable_entity }
end
end
end
在update action里,Rails通过:id参数找到要编辑的数据。 接着update_attributes会根据表单传进来的参数修改到数据上。 如果一切正常,使用者会被指向到文章的show页面。 如果验证有任何问题,它会显示edit页面好让使用者可以修正数据。
6.12 删除文章
最后,点击destroy超链接会调用destroy action:
def destroy
@post = Post.find(params[:id])
@post.destroy
respond_to do |format|
format.html { redirect_to(posts_url) }
format.xml { head :ok }
end
end
Active Record model的destroy函数会删除对应的数据库数据。 完成之后,就没办法显示咯,所以Rails 将使用者指向这个model 的index 页面。
7 新增第二个Model
你已经完成用scaffolding 功能建立一个model 了,接下来让我们再新增第二个model。 第二个model 是博客文章的留言。
7.1 产生Model
Rails 的Models 名称都是单数名词,而它们对应的据库表是复数名词,这个惯例也适用在新的model 名字:Comment。 即使你完全不用scaffolding,大部分的Rails 开发者也都会用生成器(generators)来产生models 及controllers 文件。 要建立一个新的model,请在终端中输入:
$ rails generate model Comment commenter:string body:text
post:references
这个指令会产生以下文件:
- app/models/comment.rb – Model文件
- db/migrate/20100207235629_create_comments.rb – Migration文件
- test/unit/comment_test.rb and test/fixtures/comments.yml –测试文件
首先,让我们看一下comment.rb :
class Comment < ActiveRecord::Base
belongs_to :post
end
这看起来跟先前的post.rb model非常像。 差别是多了一行belongs_to :post ,这会设定Active Record的association(关联) 。 你将会在下一节学到更多associations 的知识。
除了model,Rails 也会建立对应的据库表migration:
class CreateComments < ActiveRecord::Migration
def self.up
create_table :comments do |t|
t.string :commenter
t.text :body
t.references :post
t.timestamps
end
end
def self.down
drop_table :comments
end
end
注意到t.references这一行会帮关联的models建立foreign key (外键)栏位(译注:等同于t.integer :post_id )。 接着让我们执行Migration:
$ rake db:migrate
Rails 很聪明只会执行还没有执行过的Migrations,所以在这个例子中,我们只会看到:
== CreateComments: migrating =================================================
-- create_table(:comments) -> 0.0017s == CreateComments: migrated
(0.0018s) ========================================
7.2 把Models
关联起来
Active Record associations 让你可以轻易声明两个Models 之间的关系。 在这个文章跟留言的例子,你可以写出以下的关系:
每篇留言(comment)属于一篇文章(post)
一篇文章(post)有许多留言(comments)
事实上,这就非常接近Rails 用来声明关系的语法了。 你已经见到Comment model 里面的代码,声明了每篇留言属于一篇文章:
class Comment < ActiveRecord::Base
belongs_to :post
end
你会需要编辑post.rb文件加上另一头的关联声明:
class Post < ActiveRecord::Base
validates :name, :presence => true
validates :title, :presence => true,
:length => { :minimum => 5 }
has_many :comments
end
这两行声明语法产生了一些神奇的行为。 例如,如果你有一篇文章的实例变量@post ,你就可以通过@post.comments拿到所有的留言列表了。
关于更多Active Record associations的信息,请参阅Active Record Associations .
7.3为留言新增URL路由
如同home controller,我们也需要新增路由告诉Rails如何浏览comments 。 再次打开config/routes.rb ,你会看到一段之前由scaffold生成器为posts产生的resources :posts代码,请修改成:
resources :posts do
resources :comments
end
这会在posts里建立一个comments的nested resource (嵌套resource) 。 这也描述了文章和留言有着阶层关系。
关于路由的更多信息,请参阅Rails Routing from the Outside In
7.4 产生Controller
有了Model,我们来把注意力放到如何建立对应的controller。 再一次使用生成器:
$ rails generate controller Comments
这会建立四个文件和一个空目录:
- app/controllers/comments_controller.rb – Controller文件
- app/helpers/comments_helper.rb – View helper文件
- test/functional/comments_controller_test.rb – Controller的功能测试
- test/unit/helpers/comments_helper_test.rb – Helper的单元测试
- app/views/comments/ – Controller的Views文件所在目录
就像任何博客,我们的读者可以在看完文章之后留言,然后回到文章页面看到刚刚的留言。 所以,我们的CommentsController会提供函数可以建立留言跟删除垃圾留言。
首先,让我们修改Post的show模板( /app/views/posts/show.html.erb )好让我们可以新增留言:
<p class="notice"><%= notice %></p>
<p>
<b>Name:</b>
<%= @post.name %>
</p>
<p>
<b>Title:</b>
<%= @post.title %>
</p>
<p>
<b>Content:</b>
<%= @post.content %>
</p>
<h2>Add a comment:</h2>
<%= form_for([@post, @post.comments.build]) do |f| %>
<%= f.error_messages %>
<div class="field">
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
</div>
<div class="field">
<%= f.label :body %><br />
<%= f.text_area :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<%= link_to 'Edit Post', edit_post_path(@post) %> |
<%= link_to 'Back to Posts', posts_path %> |
我们在Post show页面新增了一个表单可以建立新留言,这个表单提交后会调用CommentsController的create action。 让我们继续:
class CommentsController < ApplicationController
def create
@post = Post.find(params[:post_id])
@comment = @post.comments.create(params[:comment])
redirect_to post_path(@post)
end
end
看起来比之前的posts controller 复杂一点。 这是因为有了阶层关系。 每一篇留言必须追踪它是属于哪一篇文章,因此需要一开始就得用find 找到所属的Post model。
此外,这里也用到一些association 所提供的函数。 我们在@post.comments上使用create函数来新增并储存。 这会自动关联起该留言属于该特定文章。
一旦我们完成新增留言,我们使用post_path(@post) helper来把使用者重新指向到本来的文章页面。 这我们之前看过了,会调用PostsController的show action显示show.html.erb模板。 这个页面也将用来显示留言,让我们在app/views/posts/show.html.erb新增以下代码:
<p class="notice"><%= notice %></p>
<p>
<b>Name:</b>
<%= @post.name %>
</p>
<p>
<b>Title:</b>
<%= @post.title %>
</p>
<p>
<b>Content:</b>
<%= @post.content %>
</p>
<h2>Comments</h2>
<% @post.comments.each do |comment| %>
<p>
<b>Commenter:</b>
<%= comment.commenter %>
</p>
<p>
<b>Comment:</b>
<%= comment.body %>
</p>
<% end %>
<h2>Add a comment:</h2>
<%= form_for([@post, @post.comments.build]) do |f| %>
<%= f.error_messages %>
<div class="field">
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
</div>
<div class="field">
<%= f.label :body %><br />
<%= f.text_area :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<br />
<%= link_to 'Edit Post', edit_post_path(@post) %> |
<%= link_to 'Back to Posts', posts_path %> |
现在我们可以在你的博客上新增文章跟留言了。
8 重构
文章跟留言都可以运行了,但是如果我们看看app/views/posts/show.html.erb模板,实在有点又臭又长。 我们可以利用partials 来加以改善。
8.1 显示Partial
Collections (集合)
首先,我们来建立一个partial 来显示文章的所有留言。 新增app/views/comments/_comment.html.erb文件加入以下程序:
<p>
<b>Commenter:</b>
<%= comment.commenter %>
</p>
<p>
<b>Comment:</b>
<%= comment.body %>
</p>
然后修改app/views/posts/show.html.erb如下:
<p class="notice"><%= notice %></p>
<p>
<b>Name:</b>
<%= @post.name %>
</p>
<p>
<b>Title:</b>
<%= @post.title %>
</p>
<p>
<b>Content:</b>
<%= @post.content %>
</p>
<h2>Comments</h2>
<%= render @post.comments %>
<h2>Add a comment:</h2>
<%= form_for([@post, @post.comments.build]) do |f| %>
<%= f.error_messages %>
<div class="field">
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
</div>
<div class="field">
<%= f.label :body %><br />
<%= f.text_area :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<br />
<%= link_to 'Edit Post', edit_post_path(@post) %> |
<%= link_to 'Back to Posts', posts_path %> |
这将为
post.comments<notextile><tt> 中的每篇留言都套用</tt></notextile>app/views/comments/_comment.html.erb<notextile><tt>
這個partial。每次render 函数迭代</tt></notextile>
post.comments<notextile><tt> 中的每篇留言都套用</tt></notextile>app/views/comments/_comment.html.erb<notextile><tt>
這個partial。每次render 函数迭代</tt></notextile>
post.comments ,它会把每一篇留言指定到一个与partial同名的区域变量(local variable),在这个例子中,就可以在partial里面使用。 (译注:也就是在 _comment.html.erb+这个partial里面的comment变量就是一篇篇的留言)
8.2 显示Partial
表单
让我们也把新增留言的部分移到partial 去吧。 同样地,我们新增app/views/comments/_form.html.erb内容是:
<%= form_for([@post, @post.comments.build]) do |f| %>
<%= f.error_messages %>
<div class="field">
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
</div>
<div class="field">
<%= f.label :body %><br />
<%= f.text_area :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
然后编辑app/views/posts/show.html.erb如下:
<p class="notice"><%= notice %></p>
<p>
<b>Name:</b>
<%= @post.name %>
</p>
<p>
<b>Title:</b>
<%= @post.title %>
</p>
<p>
<b>Content:</b>
<%= @post.content %>
</p>
<h2>Comments</h2>
<%= render @post.comments %>
<h2>Add a comment:</h2>
<%= render "comments/form" %>
<br />
<%= link_to 'Edit Post', edit_post_path(@post) %> |
<%= link_to 'Back to Posts', posts_path %> |
其中第二个render定义了要显示comments/form这个模板,Rails会根据其中的斜线去找app/views/comments目录下的_form.html.erb文件。
因为@posts被定义成实例变量(instance
variable),所以可以在所有的partials中读取到。
9 删除留言
另一个博客的重要功能是可以删除垃圾留言。 要办到这件事,我们需要在view中有个超链接,以及在controller中实作DELETE动作。
首先,让我们在app/views/comments/_comment.html.erb partial加上删除的超链接:
<p>
<b>Commenter:</b>
<%= comment.commenter %>
</p>
<p>
<b>Comment:</b>
<%= comment.body %>
</p>
<p>
<%= link_to 'Destroy Comment', [comment.post, comment],
:confirm => 'Are you sure?',
:method => :delete %>
</p>
点击“Destroy Comment”链接会提交DELETE /posts/:id/comments/:id到CommentsController ,我们接下来要找到要删除的留言,让我们在controller里加入destroy action:
class CommentsController < ApplicationController
def create
@post = Post.find(params[:post_id])
@comment = @post.comments.create(params[:comment])
redirect_to post_path(@post)
end
def destroy
@post = Post.find(params[:post_id])
@comment = @post.comments.find(params[:id])
@comment.destroy
redirect_to post_path(@post)
end
end
这个destroy action会先找到所属的文章,然后通过这篇文章的@post.comments集合找到该留言,接着从数据库中移除,最后把使用者指向show action。
9.1 删除关联的对象
如果你要删除一篇文章,那么其关联的留言也需要被一起删除。 不然的话这些留言只会白白占据你的数据库。 Rails支援在association关联上使用dependent选项来解决这件事情。 修改Post model,即app/models/post.rb如下:
class Post < ActiveRecord::Base
validates :name, :presence => true
validates :title, :presence => true,
:length => { :minimum => 5 }
has_many :comments, :dependent => :destroy
end
10 安全性
如果你打算部署这个博客,任何人都可以新增、修改、删除文章或删除留言。
Rails内建了一个非常简单的HTTP认证系统可以处理这种情形。 首先,我们在app/controllers/application_controller.rb启用simple HTTP based authentication:
class ApplicationController < ActionController::Base
protect_from_forgery
private
def authenticate
authenticate_or_request_with_http_basic do |user_name, password|
user_name == 'admin' && password == 'password'
end
end
end
当然你可以修改成你想要的使用者名称和密码。 我们把这个函数放进ApplicationController里,如此所有controller都可以使用(译注:因为所有的controller都继承自ApplicationController )。
接着在PostsController里,我们要对需要认证的actions加上权限检查,这里我们使用Rails的before_filter函数,它允许我们在执行特定的actions前先执行指定的函数,而我们在这个函数中检查使用者是否有权限。
我们在PostsController的上方来加入before filter。 在这个例子中,我们希望使用者验证除了index跟show之外的所有action,请这么写:
class PostsController < ApplicationController
before_filter :authenticate, :except => [:index, :show]
# GET /posts
# GET /posts.xml
def index
@posts = Post.all
respond_to do |format|
# snipped for brevity
我们也希望有权限的使用者才可以删除留言,所以在CommentsController加上:
class CommentsController < ApplicationController
before_filter :authenticate, :only => :destroy
def create
@post = Post.find(params[:post_id])
# snipped for brevity
这样当你试着建立一篇新文章,你会需要先经过basic HTTP Authentication认证。

11 建立一个有多个Model 的表单
另一个博客常见的功能是可以为文章下标签(tag)。 要实作这个功能,你的应用程序必须在一个表单中操作不只一个model。 Rails 提供了nested forms (内嵌的表单)。
要示范这项功能,我们将在你新增文章的地方,也可以顺便下标签。 首先,建立一个新的标签Model:
$ rails generate model tag name:string post:references
同样的,执行migration 来建立数据库表:
$ rake db:migrate
接着,编辑post.rb文件来建立关联。 接着告诉Rails (通过accepts_nested_attributes marco宏)你希望通过文章来设定标签:
class Post < ActiveRecord::Base
validates :name, :presence => true
validates :title, :presence => true,
:length => { :minimum => 5 }
has_many :comments, :dependent => :destroy
has_many :tags
accepts_nested_attributes_for :tags, :allow_destroy => :true,
:reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } }
end
其中的:allow_destroy选项告诉Rails在稍后的view中会显示“remove” checkbox。 而:reject_if选项会阻止储存空的标签。
修改views/posts/_form.html.erb来显示标签的partial:
<% @post.tags.build %><%= form_for(@post) do |post_form| %><% if @post.errors.any? %><div id="errorExplanation"><h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2><ul><% @post.errors.full_messages.each do |msg| %><li><%= msg %></li><% end %></ul></div><% end %><div class="field"><%= post_form.label :name %><br /><%= post_form.text_field :name %></div><div class="field"><%= post_form.label :title %><br /><%= post_form.text_field :title %></div><div class="field"><%= post_form.label :content %><br /><%= post_form.text_area :content %></div><h2>Tags</h2><%= render :partial => 'tags/form',:locals => {:form => post_form} %><div class="actions"><%= post_form.submit %></div><% end %>
注意到为了接下来代码的可读性,我们修改了form_for(@post) do |f|的f变成post_form 。
这个范例也展示了render helper 可以接受locals 参数来传递区域变量。 在这个例子中,partial里面的区域变量form指的就是post_form对象。
我们也在表单上方新增一行@post.tags.build ,这会确保有空的标签对象可以被使用者编辑,不然的话标签表单没办法显示。
建立app/views/tags目录,以及_form.html.erb文件,其内容是标签的表单:
<%= form.fields_for :tags do |tag_form| %><div class="field"><%= tag_form.label :name, 'Tag:' %><%= tag_form.text_field :name %></div><% unless tag_form.object.nil? || tag_form.object.new_record? %><div class="field"><%= tag_form.label :_destroy, 'Remove:' %><%= tag_form.check_box :_destroy %></div><% end %><% end %>
最后,我们编辑app/views/posts/show.html.erb模板来显示标签。
<p class="notice"><%= notice %></p>
<p>
<b>Name:</b>
<%= @post.name %>
</p>
<p>
<b>Title:</b>
<%= @post.title %>
</p>
<p>
<b>Content:</b>
<%= @post.content %>
</p>
<p>
<b>Tags:</b>
<%= @post.tags.map { |t| t.name }.join(", ") %>
</p>
<h2>Comments</h2>
<%= render @post.comments %>
<h2>Add a comment:</h2>
<%= render "comments/form" %>
<%= link_to 'Edit Post', edit_post_path(@post) %> |
<%= link_to 'Back to Posts', posts_path %> |
通过这些修改,你就可以在同一个view 中同时编辑文章跟标签了。
不过呢,那个@post.tags.map { |t| t.name }.join(", ")实在有点丑,我们可以把它变成helper函数。
12 View Helpers
View Helpers (辅助函数)放在app/helpers目录下,提供一些可以被重复使用的Views函数。 在这个例子,我们希望有个字串函数可以把一群对象中的name 属性用逗号串接在一起。 因为这用在Post show 模板,所以我们把它放在PostsHelper 里。
打开app/helpers/posts_helper.rb加入以下程序:
module PostsHelperdef join_tags(post)post.tags.map { |t| t.name }.join(", ")endend
编辑app/views/posts/show.html.erb view如下:
<p class="notice"><%= notice %></p><p><b>Name:</b><%= @post.name %></p><p><b>Title:</b><%= @post.title %></p><p><b>Content:</b><%= @post.content %></p><p><b>Tags:</b><%= join_tags(@post) %></p><h2>Comments</h2><%= render @post.comments %><h2>Add a comment:</h2><%= render "comments/form" %><%= link_to 'Edit Post', edit_post_path(@post) %> |<%= link_to 'Back to Posts', posts_path %> |
13 接下来?
到目前为止,你已经建立了你的第一个Rails 应用,请随意修改实验你的程序。 不过请不要埋头苦干,当你需要协助的时候,请看以下资源:
- Ruby On Rails guides
- The Ruby on Rails Tutorial
- Ruby on Rails mailing list
- #rubyonrails channel on irc.freenode.net
- Rails Wiki
- 译注: Ruby Wednesday定期聚会
- 译注: ruby-tw #ruby-tw channel on irc.freenode.net
- 译注: ppt.cc的Ruby版
- 译注: RailsFun!
你也可以通过Rails 内建的工具来产生文件:
执行rake doc:guides会产生一份完整的Rails指南在你的应用程序doc/guides目录下。 用浏览器打开doc/guides/index.html就可以了。
执行rake doc:rails会产生一份API
documentation文件在doc/api目录下。 请打开doc/api/index.html
。
14 一些设定上的诀窍
最简单的方式就是把所有外部数据都当作UTF -8。 如果不是的话,类库跟Rails会需要转换你的数据变成UTF -8,这可能会发生问题。 所以最好的方式还是让所有的外部数据都是UTF -8。
常见的症兆是在你的浏览器中出现了带有问号的小黑钻石,或是“ü” 变成"ü"。 Rails 内部可以自动检测然后修正。 但是,如果你有外部数据不是UTF -8,它还是可能无法自动帮你检测和修正。
两种常见的非UTF -8原因:
你的文字编辑器:大部分的文字编辑器(例如Textmate)预设会存成UTF -8。 如果你的不是,这会导致你在模板中输入的文字(例如é),在浏览器中会变成带有问号的小黑钻石。 同样地,在你的I18N 翻译文件也可能发生。 大部分预设不是UTF -8的编辑器(例如某些版本的Dreamweaver)可以修改预设值,请改成UTF -8。
你的数据库。 Rails预设会从数据库出来的数据转成UTF -8。 但是,如果你的数据库内部不是UTF -8,那么可能没办法存进所有使用者输入的字节。 例如,你的使用者输入俄文、希伯来文或是日文字节,而你的数据库内部使用Latin-1,那输入的数据就会在进数据库时不见。 所以可能的话,让数据库也使用UTF -8。
15 文件修改记录
- July 12, 2010: Fixes, editing and updating of code samples by Jaime Iniesta
- May 16, 2010: Added a section on configuration gotchas to address common encoding problems that people might have by Yehuda Katz
- April 30, 2010: Fixes, editing and updating of code samples by Rohit Arondekar
- April 25, 2010: Couple of more minor fixups Mikel Lindsaar
- April 1, 2010: Fixed document to validate XHTML 1.0 Strict. Jaime Iniesta
- February 8, 2010: Full re-write for Rails 3.0-beta, added helpers and before_filters, refactored code by Mikel Lindsaar
- January 24, 2010: Re-write for Rails 3.0 by Mikel Lindsaar
- July 18, 2009: Minor cleanup in anticipation of Rails 2.3.3 by Mike Gunderloy
- February 1, 2009: Updated for Rails 2.3 by Mike Gunderloy
- November 3, 2008: Formatting patch from Dave Rothlisberger
- November 1, 2008: First approved version by Mike Gunderloy
- October 16, 2008: Revised based on feedback from Pratik Naik by Mike Gunderloy (not yet approved for publication)
- October 13, 2008: First complete draft by Mike Gunderloy (not yet approved for publication)
- October 12, 2008: More detail, rearrangement, editing by Mike Gunderloy (not yet approved for publication)
- September 8, 2008: initial version by James Miller (not yet approved for publication)
16 关于译者
17 翻译词汇
本文翻译自http://guides.rails.info/getting_started.html 。 以下是英文与简体中文的对照词汇:
原文 中文
- class 类
- object 对象
- instance 实例
- instantiate 实例化
- instance variable 实例变量
- local variable 区域变量
- inherit 继承
- interface 接口
- library 类库
- server 服务器
- database 数据库
- (database) table 数据库表
- code 代码
- command-line 指令
- terminal 终端
- method 函数
- application 应用程序, 应用
- framework 框架
- template 模板
- layout 版式
- template rendering
模板渲染
- request HTTP请求
- timestamp 时间戳
- form 表单
- array 列表
- iterate 迭代
- escaped 逸出
- tag 标签
- attribute 属性
- routing 路由
- collection 集合
- macro 宏
以下包留原名词不译,必要时加上翻译注解:
原文 说明
- model 模型
- controller 控制器
- view 视图
- resource 资源
- partial 指片段的view
- schema 数据库纲要
- migration 数据库迁移
- RESTful REST的形容词
- action 指controller 的action
时不译
- view helper View辅助程序
- development, test, production mode 指Rails 运行的环境
- HTTP verbs HTTP协定中的动词
- template rendering
模板渲染/呈现
- scaffolding, scaffold 手脚架
- timestamp 时间戳
- validation 验证
- callback 调用
- console 控制台
- hash 哈希
- generator 生成器
- association 关联
- foreign key 外键
- nested 嵌套的
- checkbox
- Plugin 插件
- block 代码块
4条评论
游客 小龙 说:
2010-11-09 08:14:15
你在这行也算是前辈了,来点原创的有深度的教程吧,还有有什么办法可以减少局部模板代码量啊,非常不习惯现在的写一个,再复制一个命名为原名字前加_名字的,感觉不符合RAILS的DRY原则
panjj 说:
2010-11-10 04:29:15
开始已经声明,主要是翻译!参考了官方文档和繁体版的!并不是原创性的文章!it行本身就是问题简单化!这行我不算前辈,写简单性的东西,是我所追求的目标!见谅!
游客 昌是是 说:
2010-10-10 12:55:57
晶昌是昌是是