看吧,看吧,Rails 2.0 就要来了。但在我们盖上最终的印章之前,我们将要经历几个试发行阶段。第一个就是这个预览版,它能让你在几乎完成的状态下体验这些新特性。
我们可能会对一些东西进行修改或添加一些其他功能,但总的来说,Rails 2.0 的外观和感觉就是这样的。在这次发布版有机会被试用后,我们将进入一个或两个(或三个,取决于我们需要多少个)候选发布阶段。然后,就是最终发布。
在 2.0 发布之前,我们还将发布 1.2.4 版本,其中将包含各种错误修复和最后的弃用警告,以帮助你准备将现有应用程序升级到 2.0 标准。
关于过程就说这么多。让我来告诉你一些 Rails 2.0 的新特性
Action Pack:资源
这是 2.0 版本的主要改进所在。我们在 RESTful 风格方面进行了一系列改进。首先,我们用斜杠代替了分号来定义自定义方法。所以 /people/1;edit 现在是 /people/1/edit。我们还为路由资源添加了命名空间功能,这使得将管理界面等内容限制在特定范围内变得非常容易。
map.namespace(:admin) do |admin| admin.resources :products, :collection => { :inventory => :get }, :member => { :duplicate => :post }, :has_many => [ :tags, :images, :variants ] end
这将为你提供像 inventory_admin_products_url 和 admin_product_tags_url 这样的命名路由。为了跟踪这些命名路由的激增,我们添加了“rake routes”任务,它将列出 routes.rb 创建的所有命名路由。
我们还引入了一个新约定,即所有基于资源的控制器默认都将是复数形式。这使得单个资源可以在多个上下文中进行映射,并且仍然指向同一个控制器。例如:
# /avatars/45 => AvatarsController#show
map.resources :avatars
# /people/5/avatar => AvatarsController#show
map.resources :people, :has_one => :avatar
Action Pack:多视图
除了对资源进行改进之外,还对多视图进行了改进。我们已经有了 #respond_to,但我们将其向前推进了一步,使其能够深入到模板。我们将模板的格式与其渲染引擎分开了。所以 show.rhtml 现在变成了 show.html.erb,这是当 show 操作声明了 format.html 时默认渲染的模板。现在你还可以使用 show.csv.erb 这样的模板,它针对 text/csv,但同时也使用默认的 ERB 渲染器。
所以模板的新格式是 action.format.renderer。一些例子:
说到 iPhone,我们让声明仅用于内部路由的“假”类型变得更容易。就像当你想要一个仅用于 iPhone 的特殊 HTML 界面时一样。只需这样做:
# should go in config/initializers/mime_types.rb
Mime.register_alias "text/html", :iphone
class ApplicationController < ActionController::Base
before_filter :adjust_format_for_iphone
private
def adjust_format_for_iphone
if request.env["HTTP_USER_AGENT"] && request.env["HTTP_USER_AGENT"][/(iPhone|iPod)/]
request.format = :iphone
end
end
end
class PostsController < ApplicationController
def index
respond_to do |format|
format.html # renders index.html.erb
format.iphone # renders index.iphone.erb
end
end
end
我们鼓励你在 config/initializers/mime_types.rb 文件中声明自己的 mime 类型别名。此文件默认包含在所有新应用程序中。
Action Pack:记录标识
基于对资源的新推动,对处理 URL 的控制器和视图方法进行了一系列简化。我们增加了一些约定,用于即时将模型类转换为资源路由。例如:
# person is a Person object, which by convention will
# be mapped to person_url for lookup
redirect_to(person)
link_to(person.name, person)
form_for(person)
Action Pack:HTTP 友好
正如你可能已经了解到的,Rails 2.0 中的 Action Pack 致力于与 HTTP 及其所有优点更加紧密地结合。资源、多重表示,但还有更多。我们添加了一个新模块来处理 HTTP 基本身份验证,这被证明是 SSL 上进行 API 身份验证的绝佳方式。它非常简单易用。这是一个例子(ActionController::HttpAuthentication 中有更多例子):
class PostsController < ApplicationController
USER_NAME, PASSWORD = "dhh", "secret"
before_filter :authenticate, :except => [ :index ]
def index
render :text => "Everyone can see me!"
end
def edit
render :text => "I'm only accessible if you know the password"
end
private
def authenticate
authenticate_or_request_with_http_basic do |user_name, password|
user_name == USER_NAME && password == PASSWORD
end
end
end
我们还使将 JavaScript 和样式表文件组织成逻辑单元变得更加容易,而不会因为请求大量文件而受到 HTTP 开销的干扰。使用 javascript_include_tag(:all, :cache => true) 将在生产环境中将 public/javascripts/.js 合并成一个 public/javascripts/all.js 文件,同时在开发环境中保持文件分开,以便你在不清除缓存的情况下进行迭代式工作。
同样,我们还添加了一个选项来欺骗那些不希望自己进行请求管道化的浏览器。如果我们将 ActionController::Base.asset_host 设置为 “assets%d.example.com”,我们将自动将你的资源调用(如 image_tag)分发到 asset1 到 asset4。这允许浏览器同时打开更多连接,并提高应用程序的感知速度。
Action Pack:安全
开箱即用地创建安全应用程序始终是我们的荣幸,在 Rails 2.0 中,我们从多个方面实现了这一点。最重要的是,我们现在内置了处理 CRSF 攻击的机制。通过在所有表单和 Ajax 请求中包含一个特殊令牌,你可以防止来自应用程序外部的请求。所有这些在新的 Rails 2.0 应用程序中默认启用,你可以通过 ActionController::Base.protect_from_forgery(请参阅 ActionController::RequestForgeryProtection 以了解更多信息)轻松地在现有应用程序中启用它。
我们还使处理 XSS 攻击变得更容易,同时仍然允许用户在你的页面中嵌入 HTML。旧的 TextHelper#sanitize 方法已从黑名单(非常难以保持安全)方法转变为白名单方法。如果你已经在进行使用 sanitize,你将自动获得更好的保护。你还可以使用 sanitize 调整默认允许的标签。详情请参阅 TextHelper#sanitize。
最后,我们添加了对 HTTP Only Cookie 的支持。并非所有浏览器都支持它们,但你可以在支持它们的浏览器中使用它们。
Action Pack:异常处理
许多常见异常在共享级别而不是每个操作级别进行捕获会更好。这一直都是可能的,通过重写 rescue_action_in_public,但那样的话你必须自己实现 case 语句并调用 super。呸。所以现在我们有一个类级别的宏叫做 rescue_from,你可以用它来声明式地将特定异常指向给定的操作。例如:
class PostsController < ApplicationController
rescue_from User::NotAuthorized, :with => :deny_access
protected
def deny_access
...
end
end
Action Pack:杂项
同样值得注意的是 AtomFeedHelper,它使用增强的 Builder 语法使创建 Atom feed 更加简单。简单示例:
# index.atom.builder:
atom_feed do |feed|
feed.title("My great blog!")
feed.updated((@posts.first.created_at))
for post in @posts
feed.entry(post) do |entry|
entry.title(post.title)
entry.content(post.body, :type => 'html')
entry.author do |author|
author.name("DHH")
end
end
end
end
我们进行了一些性能改进,因此资产标签调用现在更便宜,我们还缓存了简单的命名路由,使其速度更快。
最后,我们已将 in_place_editor 和 autocomplete_for 移到官方 Rails SVN 上的插件中。
Active Record:性能
Active Record 进行了大量的修复和小型调整,但大型新功能相对较少。不过,我们确实添加了一个非常简单的查询缓存,它可以在同一请求中识别相似的 SQL 调用并返回缓存的结果。这对于难以使用 :include 或其他机制处理的 N+1 情况尤其有用。我们还极大地提高了 fixtures 的性能,使得大多数基于正常 fixture 使用的测试套件速度提高了 50-100%。
Active Record:优雅的迁移
现在有了一种新的替代格式来以稍微更有效的方式声明迁移。以前你会这样写:
create_table :people do |t| t.column, “account_id”, :integer t.column, “first_name”, :string, :null => false t.column, “last_name”, :string, :null => false t.column, “description”, :text t.column, “created_at”, :datetime t.column, “updated_at”, :datetime end
现在你可以写:
create_table :people do |t| t.integer :account_id t.string :first_name, :last_name, :null => false t.text :description t.timestamps end
Active Record:XML 输入,JSON 输出
Active Record 一直支持序列化到 XML。在 2.0 中,我们增加了反序列化功能,所以你可以说 Person.new.from_xml(“
Active Record:精简
为了让 Active Record 更精简、更强大,我们移除了 acts_as_XYZ 功能,并将它们放入 Rails SVN 仓库中的独立插件。所以如果你使用 acts_as_list,你只需要执行 ./script/plugin install acts_as_list 即可,一切都会像什么都没发生过一样。
更彻底地说,我们还将所有商业数据库适配器推向了自己的 gem。因此,Rails 现在只附带 MySQL、SQLite 和 PostgreSQL 的适配器。这些是我们有容易且乐意测试的数据库。但这并不意味着商业数据库被抛弃了。相反,它们现在已经可以独立于主要的 Rails 发行版进行发布了。这可能是一件好事,因为商业数据库通常需要更多的例外处理和额外的步骤才能正常工作。
商业数据库适配器现在存在于遵循相同命名约定的 gem 中:activerecord-XYZ-adapter。所以如果你 gem install activerecord-oracle-adapter,你将立即在同一台机器上的所有 Rails 应用程序中获得 Oracle 作为适配器选项。你甚至不需要更改应用程序中的任何一行代码来使用它。
这也意味着新的数据库适配器在 Rails 世界中更容易获得支持。只要你的适配器按照发布的约定进行打包,用户只需安装 gem 即可使用。
Active Record:with_scope 加上一点语法改进
ActiveRecord::Base.with_scope 已设为 protected,以阻止人们在控制器中(尤其是在过滤器中)滥用它。取而代之的是,现在鼓励你只在模型内部使用它。这正是它的设计初衷,也是它在逻辑上仍然适合的地方。当然,这都是关于鼓励和禁止的。如果你权衡了利弊,仍然想在模型外部使用 with_scope,你可以随时通过 .send(:with_scope) 来调用它。
ActionWebService 退出,ActiveResource 登场
Rails 在 SOAP 与 REST 的争论中选择了一方,这可能不会让你感到意外。除非你绝对需要使用 SOAP 进行集成,否则我们强烈不建议这样做。作为自然的延伸,我们已将 ActionWebService 从默认捆绑中移除。它只是一个 gem install actionwebservice 的距离,但这仍然传递了一个重要的信息。
与此同时,我们将新的 ActiveResource 框架从 beta 版中移出,并纳入了默认捆绑。ActiveResource 就像 ActiveRecord,但用于资源。它遵循类似的 API,并配置为与使用资源驱动方法的 Rails 应用程序“开箱即用”。例如,一个普通的脚手架将可以通过 ActiveResource 访问。
ActiveSupport
ActiveSupport 中新内容不多。我们增加了一系列新方法,如 Array#rand 用于从数组中获取随机元素,Hash#except 用于从哈希中过滤掉不需要的键,以及对 Date 的大量扩展。我们还通过 assert_difference 使测试更加方便。除此之外,基本上都是修复和调整。
Action Mailer
这是 Action Mailer 的一个非常小的更新。除了少数错误修复外,我们还增加了注册替代模板引擎的选项以及测试套件中的 assert_emails,其工作方式如下:
Rails:调试器回来了
总而言之,Rails 在整体上进行了一系列改进。其中我最喜欢的是断点的回归,形式是调试器。它是一个真正的调试器,不仅仅是 IRB 的转储。你可以前后步进,列出当前位置,等等。这一切都归功于 ruby-debug gem 的慷慨贡献。所以你需要安装它才能使用新的调试器。
要使用调试器,只需安装 gem,在你的应用程序中放置“debugger”在某个地方,然后用 —debugger 或 -u 启动服务器。当代码执行到 debugger 命令时,你将在运行服务器的终端中直接访问它。无需 script/breakpointer 或其他任何东西。你也可以在测试中使用调试器。
Rails:整理你的环境
在 Rails 2.0 之前,各个地方的 config/environment.rb 文件都会充斥着各种一次性的配置细节。现在你可以将这些元素收集到独立的配置文件中,并将它们放在 config/initializers 下,它们将自动加载。新的 Rails 2.0 应用程序默认包含两个示例:inflections.rb(用于自定义复数规则)和 mime_types.rb(用于自定义 MIME 类型)。这应该意味着你只需要在 config/environment.rb 中保留默认设置。
Rails:更轻松的插件排序
既然我们已经将相当一部分内容从 Rails 中提取到插件中,你可能会有其他插件依赖于这些功能。这可能需要你先加载 acts_as_list,然后再加载你自己的 acts_as_extra_cool_list 插件,以便后者能够扩展前者。
以前,这需要你在 config.plugins 中命名 *所有* 你的插件。当你只想说“我只关心 acts_as_list 在其他所有插件之前加载”时,这会非常麻烦。现在你可以通过 config.plugins = [ :acts_as_list, :all ] 来做到这一点。
以及数百项其他改进
我上面谈到的只是 2.0 版本全貌的一小部分。Rails 2.0 中包含了数以百计的错误修复、调整和功能增强。所有这些都来自于大量热情的贡献者的辛勤工作,他们不知疲倦地以小而重要的方式改进框架。
我鼓励你仔细阅读 CHANGELOGs,以了解所有更改的更多信息。
那么如何升级?
如果你想将你的应用程序迁移到 Rails 2.0,你应该首先将其迁移到 Rails 1.2.3。这将包含我们从 2.0 中移除的大部分内容的弃用警告。所以如果你的应用程序在 1.2.3 版本上运行良好且没有弃用警告,那么它很可能将在 2.0 版本上直接运行。当然,如果你使用了分页等功能,你需要安装 classic_pagination 插件。如果你使用 Oracle,你需要安装 activerecord-oracle-adapter gem。依此类推,所有提取的内容都需要进行相应处理。
要通过 gem 安装预览版,请执行:
gem install rails —source http://gems.rubyonrails.org
要尝试从 SVN 标签进行安装,请使用:
rake rails:freeze:edge TAG=rel_2-0-0_PR
我们也将很快发布 Rails 1.2.4,其中将包含一些更多的弃用警告,以便你在 2.0 发布前做好准备。
无论如何,正如我开头解释的那样,这是一个预览版。使用它来感受 2.0 的氛围。看看你的现有应用程序可能需要进行哪些调整。并尝试从头开始创建一个新应用程序,以了解新的默认设置。几周后,我们将开始发布候选版本。
感谢所有参与 Rails 2.0 开发的人。我们为此工作了六个多月,终于能够与更广泛的受众分享它,这真是太棒了。请尽情享用!