我们在 Edge Rails 上针对新帖子进行过一段时间的讨论。我真的很想念它们,而且进行了大量的更改,无论大小,都经历了时间的考验。在这篇帖子中,我将详细介绍过去一周左右 Rails 中发生的一切。除此之外,你应该会看到更频繁且更定期的更新,了解当前发生的一切。
这是一个相当 次要的更改,除非你仍将在你的 database.yml
中将 SQLite 数据库称为 dbfile
。 dbfile
选项键现在已消失,很久以前就已被更标准的 database
键取代。因此,如果你在更新后突然看到“没有指定数据库文件
”错误,那么这可能是你的问题所在。
Sava Chankov 提供了一个补丁 来修复 Content-length,该补丁错误地计算了使用 Ruby 1.9 和多字节字符的 HTTP 响应头部。内容长度现在基于 String#bytesize
而不是 String#size
来计算。这利用了 Ruby 1.9 中内置的多字节字符支持,只要你一直记得用正确的编码标头(即 # encoding: utf-8
)适当地标记多字节文件即可。
一些春季清理,主要通过 Rack 支持实现,允许 Edge 移交栈的一些额外职责。其中最有趣的是现在将一些内容长度计算从你的网络服务器卸掉,而不是直接从 Rails 中进行处理。这样做的好处并不在于应用程序开发人员,而是在于你中间件的开发人员。这意味着当你操作 HTTP 响应的主体时你不再需要重新计算内容长度。
这似乎不会影响前述 Sava 的更新,因为他的修正似乎主要影响了直接通过 Rails 流式传输文件响应。
缓存控制现在由内部哈希而不是独立字符串值来处理。旧版且已破损:headers['Cache-Control'] = 'private'
,新特性:response.cache_control[:public] = true
。附加cache_control
选项包括::public
、:max_age
、:must_revalidate
以及非常直观的:extras
,它主要用于自定义标题内容。
Geoff Buesing 针对Time
提供了一个有用修复,尤其是在与 ActiveRecord 一起使用时。现在,无论默认时区配置如何,你都可以使用任何喜欢的本地时区存储和搜索 ActiveRecord 对象,并且现在一切都能工作了。你无需再担心将用户的本地时间转换成默认应用程序时间,反之亦然。
ActiveRecord 现在可以轻松访问 ActiveModel 的StateMachine
实现。或许你有所不知,但我总能找到途径将状态机引入我的 Rails 应用程序,现在构建状态机(乃至相当复杂的状态机)变得更容易了。
有关ActiveModel::StateMachine
的示例,以及如何使用它的思路,请查看我在 Envy Labs 发表的更详细博文。
Paul Gillard 提交了一个补丁程序,现在可以针对 ActiveRecord 属性自定义后缀(这并非新鲜事)和前缀(哈哈,这可是新鲜事!)。这样就能访问attribute_method_prefix
、attribute_method_suffix
以及attribute_method_affix
。虽然听起来可能有点傻,但看看这个
class Person < ActiveRecord::Base
attribute_method_affix :prefix => 'me_mateys_', :suffix => '_is_in_pirate?'
private
def me_mateys_attribute_is_in_pirate?(attr)
send(attr).to_s =~ /\bYAR\b/i
end
end
person = Person.find(1)
person.name #=> 'Paul Gillard'
person.profession #=> 'A Pirate, yar!'
person.me_mateys_name_is_in_pirate? #=> false
person.me_mateys_profession_is_in_pirate? #=> true
好吧,这仍然有点傻,但希望你明白了这一点,并且能想到一些自己的使用场景。所以,基本上,你现在可以添加自己的动态 ActiveRecord 方法,这些方法可能会影响它的部分或全部属性。
Paul Gillard 发布了另一个有用的补丁程序,利用前面提到的补丁程序,现在为我们提供了此语法糖:reset_attribute!
他还向我们展示了一个自己设计的海盗来展示这个新功能
pirate = Pirate.create!(:catchphrase => 'Yar!')
pirate.catchphrase = 'Ahoy!'
pirate.reset_catchphrase!
assert_equal "Yar!", pirate.catchphrase
assert_equal Hash.new, pirate.changes
assert !pirate.catchphrase_changed?
谁都不喜欢脏兮兮的海盗。