2006年11月23日,星期四

Rails 1.2:候选版本 1

作者:David

距离上一个引入 RJS、respond_to、预加载(eager loading)等功能的 Rails 主要版本发布已经过去了将近八个月。现在是时候推出我们在此期间打磨的最新一批重要功能了。

鉴于这是全新发布的主要版本,并且自 1.1 版本以来我们已经获得了巨大的用户支持,我们觉得有必要确保一切都能顺利运行。因此,我们发布了此候选版本,以找出新功能可能存在的任何回归或重大问题。

更新: Josh Susser 提供了更多关于这对开发者意味着什么,以及如何最好地提交新版本错误报告的信息:Josh Susser 讲述更多

新增功能

但首先,请允许我简要介绍一下您应该感到兴奋的内容。虽然这些新功能可能不像 RJS 那样具有即时的吸引力,但它们代表了从现在开始许多 Rails 应用程序的创建方式的根本性转变。

REST 和资源

REST 和对 HTTP 的整体运用是 Rails 1.2 的核心。这些功能大部分最初在我RailsConf 主题演讲中向公众介绍。观看演讲以了解 REST 对 Rails 的重要性。

然后开始考虑您的应用程序如何变得更具 RESTful 风格。您如何将一个拥有 15 个动作的控制器转变为 2-3 个新控制器,每个控制器都专注于单个资源并进行 CRUD 操作。最大的好处就隐藏在这里:一种清晰的控制器设计方法,可以降低实现者的复杂性,并使应用程序在通用 Web 中表现得更好。

为了帮助过渡,我们提供了一个脚手架生成器,它会创建一个存根 CRUD 接口,就像原始的脚手架生成器一样,但方式是 RESTful 的。您可以尝试使用“script/generate scaffold_resource”。不带参数运行,它将为您提供一个关于其工作方式和创建内容的简短介绍。

将这一切联系在一起的唯一真正的 API 元素是新的 map.resources,它用于代替 map.connect 来为基于资源的控制器配置 HTTP 动词。然后,一旦您拥有了一个喜欢资源的控制器,您就可以使用我们的动词模拟链接 link_to "Destroy", post_url(post), :method => :delete。同样,运行资源脚手架生成器将让您了解这一切如何工作。

格式和 respond_to

虽然 respond_to 自 Rails 1.1 起就已存在,但在 1.2 版本中我们进行了一个小小的调整,这对于该功能的即时可用性产生了很大的影响。这就是 :format 的魔力。所有新应用程序都将有一个额外的默认路由:map.connect ':controller/:action/:id.:format'。安装此路由后,可以想象以下示例

class WeblogController < ActionController::Base def index @posts = Post.find :all respond_to do |format| format.html format.xml { render :xml => @posts.to_xml } format.rss { render :action => “feed.rxml” } end end end

GET /weblog # 从浏览器 HTML 返回,基于 Accept 标头 GET /weblog.xml # 返回 XML GET /weblog.rss # 返回 RSS

现在不再需要使用 Accept 标头来实现这一点。这使得一切都变得更加容易。您只需在 URL 后附加 .xml 即可在浏览器中探索您的 API。您无需使用 before_filter 来查找新闻阅读器的线索,只需使用 .rss。所有这些都能自动与页面缓存和操作缓存配合使用。

当然,这种格式支持与 map.resources 结合使用效果更佳,它会自动确保一切正常工作。资源脚手架生成器甚至包含一个使用 format.xml 的示例,因此 /posts/5.xml 会被自动配置。非常巧妙!

多字节

Unicode 来袭!虽然 Rails 一直能够毫无困难地存储和显示 Unicode,但要截断、反转或获取 UTF-8 字符串的确切长度,则要复杂得多。您需要自己处理 KCODE,虽然很多人都成功了,但它并没有您希望(甚至可能期望)的那样即插即用。

由于 Ruby 要到明年此时才能支持多字节,Rails 1.2 引入了 ActiveSupport::Multibyte 来处理 Unicode 字符串。调用字符串上的 `chars` 方法即可开始处理字符而不是字节。

想象字符串 ‘€2.99’。如果我们以字节级别对其进行操作,很容易导致数据损坏

‘€2.99’[0,1] # => “\342” ‘€2.99’[0,2] # => “?” ‘€2.99’[0,3] # => “€”

€ 字符占三个字节。因此,您不仅难以对其进行字节操作,而且 String#first 和 TextHelper#truncate 也会出现问题。在过去,会出现这种情况

‘€2.99’.first # => ‘\342’ truncate(‘€2.99’, 2) # => ‘?’

有了 Rails 1.2,您自然会得到

‘€2.99’.first # => ‘€’ truncate(‘€2.99’, 2) # => ‘€2’

TextHelper#truncate/excerpt 和 String#at/from/to/first/last 会自动进行 .chars 转换,但如果您需要自己操作或显示长度,请务必调用 .chars。例如

您已编写了 <%= @post.body.chars.length %> 个字符。

有了 Rails 1.2,我们假设您希望开箱即用就能很好地处理 Unicode。因此,Action 渲染的默认字符集也为 UTF-8(您可以使用 `ActionController::Base.default_charset=(encoding)` 设置其他字符集)。KCODE 也将自动设置为 UTF-8。

观看屏幕录像。(但请注意,手动设置 KCODE 已不再是必需的)

Unicode 的需求最大,但 Multibyte 也可以处理其他编码(例如 Shift-JIS),只要它们被实现。请为您的编码扩展 Multibyte。

感谢 Manfred Stienstra、Julian Tarkhanov、Thijs van der Vossen、Jan Behrens 和(其他人?)创建了这个库。

注意事项

尽管我们已尽最大努力保持与 1.1.6 的向后兼容性,但仍有一些小范围的边缘情况需要您以特定方式进行一些修改。

路由

Action Pack 采用了全新的 Routes 实现,它更快、更安全,但也更严格。分号和句点是分隔符,因此一个曾匹配 `/download/history.txt` 的 `/download/:file` 路由现在不再起作用。使用 `:requirements => { :file => /.*/ }` 来匹配句点。

自动加载

我们修复了一个允许 Ruby 标准库中的库在引用时被自动加载的错误。以前,如果您只是引用 Pathname 常量,我们会自动加载 pathname.rb。现在不会了,您需要手动 `require 'pathname'`。

我们还改进了模块加载的处理,这意味着对 Accounting::Subscription 的引用将查找 app/models/accounting/subscription.rb。同时,这意味着仅仅引用 Subscription 将*不会*在 app/models 的任何子目录中查找 subscription.rb。只会尝试 app/models/subscription.rb。如果您出于某种原因依赖于此,可以通过在 config/environment.rb 中添加 app/models/accounting 到 config.load_paths 来恢复它。

Prototype

为了更好地符合 HTML 规范,**Prototype 的 Ajax 表单不再序列化禁用的表单元素。** 如果您依赖于禁用字段的提交,请更新您的代码。

为了保持一致性,**Prototype 的 Element 和 Field 方法不再接受任意数量的参数。** 这意味着如果您在手写 JavaScript 中使用 Element.toggle、Element.show、Element.hide、Field.clear 和 Field.present,您需要更新您的代码(Prototype 助手已更新以自动生成正确的内容)。


// if you have code that looks like this
Element.show('page', 'sidebar', 'content');
// you need to replace it with code like this
['page', 'sidebar', 'content'].each(Element.show);

Action Mailer

所有电子邮件默认都是 MIME 版本 1.0,因此您需要更新您的邮件单元测试:`@expected.mime_version = '1.0'`

弃用

自 Rails 1.0 起,我们一直保持稳定、向后兼容的 API,这样您的应用程序就可以在不进行大量工作的情况下迁移到新版本。其中一些 API 现在感觉像我们的新生体重增加,所以我们要减肥以去除脂肪。**Rails 1.2 弃用了一些现在已有更优替代方案或更适合作为插件的功能。**

弃用不是威胁,而是承诺!这些功能将在 Rails 2.0 中完全移除。您仍然可以在 1.2 版本中使用它们,但每次使用都会收到警告:在您的测试结果和日志文件中查找令人不悦的弃用警告。

让您的 1.0 时代的旧代码焕然一新。要开始,只需运行您的测试并处理警告。

安装

候选版本 gem 位于 Rails gem 仓库中。您可以这样安装它们

gem install rails —source http://gems.rubyonrails.org —include-dependencies

请注意,它会显示类似“Successfully installed rails-1.1.6.5618”的消息。这是正确的,因为在正式发布之前,我们不会使用最终版本号。

您也可以直接从 Subversion 中获取:http://dev.rubyonrails.org/svn/rails/tags/rel_1-2-0_RC1。

提交回归错误

好了。以上就是主要的变更内容,一如既往,您可以在 CHANGELOGs 中找到完整、详细的信息。在过去的八个月里,我们进行了数以百计的改进。仔细查看 CHANGELOGs 绝对值得。Ryan’s Scraps 也做得很好,注解了这些变更

但随着任何新软件版本的发布,一些以前能工作的东西将不再工作。

虽然 Rails 1.2 的目标是提供无缝的向后兼容性,但我们也是人,很有可能有些东西没有被注意到。所以,如果您正在尝试 1.2 候选版本并发现了一个错误,请务必向我们报告。在候选版本周期中,您应该遵循一些步骤来帮助我们修复您的错误。

在添加错误报告时,请务必在关键词字段中添加“1.2regression”。带有此关键词的错误会出现在一个 trac 报告中,如果您想帮忙,可以从那里开始。

如果可能,请在您的错误报告中包含一个失败的单元测试。这会使我们的工作轻松很多,并帮助其他人验证您是否找到了一个真正的问题。