1 升级到 Rails 4.0
如果您要升级现有应用程序,在进行升级之前,拥有良好的测试覆盖范围是一个好主意。您还应该首先升级到 Rails 3.2(如果您还没有升级),并确保您的应用程序在尝试升级到 Rails 4.0 之前按预期运行。有关升级时需要注意的事项列表,请参阅 升级 Ruby on Rails 指南。
2 创建 Rails 4.0 应用程序
# You should have the 'rails' RubyGem installed
$ rails new myapp
$ cd myapp
2.1 供应商化 gem
Rails 现在使用应用程序根目录中的 Gemfile
来确定您的应用程序启动所需的 gem。此 Gemfile
由 Bundler gem 处理,该 gem 然后安装所有依赖项。它甚至可以将所有依赖项本地安装到您的应用程序中,以便它不依赖于系统 gem。
更多信息:Bundler 主页
2.2 走在边缘
Bundler
和 Gemfile
使冻结 Rails 应用程序变得轻而易举,您可以使用新的专用 bundle
命令。如果您想直接从 Git 存储库捆绑,您可以传递 --edge
标志
$ rails new myapp --edge
如果您有 Rails 存储库的本地签出,并且想要使用它来生成应用程序,您可以传递 --dev
标志
$ ruby /path/to/rails/railties/bin/rails new myapp --dev
3 主要功能
3.1 升级
- Ruby 1.9.3 (提交) - 首选 Ruby 2.0;需要 1.9.3+
- 新的弃用策略 - 弃用的功能在 Rails 4.0 中是警告,将在 Rails 4.1 中删除。
- ActionPack 页面和操作缓存 (提交) - 页面和操作缓存已提取到一个单独的 gem 中。页面和操作缓存需要太多手动干预(当底层模型对象更新时手动过期缓存)。相反,请使用俄罗斯套娃缓存。
- ActiveRecord 观察者 (提交) - 观察者已提取到一个单独的 gem 中。观察者仅在页面和操作缓存中需要,并且会导致意大利面条代码。
- ActiveRecord 会话存储 (提交) - ActiveRecord 会话存储已提取到一个单独的 gem 中。在 SQL 中存储会话代价高昂。相反,请使用 cookie 会话、memcache 会话或自定义会话存储。
- ActiveModel 批量分配保护 (提交) - Rails 3 批量分配保护已弃用。相反,请使用强参数。
- ActiveResource (提交) - ActiveResource 已提取到一个单独的 gem 中。ActiveResource 未被广泛使用。
- vendor/plugins 已删除 (提交) - 使用
Gemfile
来管理已安装的 gem。
3.2 ActionPack
- 强参数 (提交) - 仅允许允许的参数更新模型对象 (
params.permit(:title, :text)
)。 - 路由关注点 (提交) - 在路由 DSL 中,将常见的子路由分解出来 (
comments
来自/posts/1/comments
和/videos/1/comments
)。 - ActionController::Live (提交) - 使用
response.stream
流式传输 JSON。 - 声明式 ETags (提交) - 添加控制器级 etag 添加,这些添加将成为操作 etag 计算的一部分。
- 俄罗斯套娃缓存 (提交) - 缓存视图的嵌套片段。每个片段根据一组依赖项(缓存键)过期。缓存键通常是模板版本号和模型对象。
- Turbolinks (提交) - 仅提供一个初始 HTML 页面。当用户导航到另一个页面时,使用 pushState 更新 URL 并使用 AJAX 更新标题和正文。
- 将 ActionView 与 ActionController 解耦 (提交) - ActionView 已与 ActionPack 解耦,将在 Rails 4.1 中移至一个单独的 gem。
- 不依赖 ActiveModel (提交) - ActionPack 不再依赖 ActiveModel。
3.3 一般
- ActiveModel::Model (提交) -
ActiveModel::Model
,一个混合类,使普通 Ruby 对象可以与 ActionPack 无缝协作(例如,用于form_for
)。 - 新的作用域 API (提交) - 作用域必须始终使用可调用对象。
- 架构缓存转储 (提交) - 为了提高 Rails 启动时间,不要直接从数据库加载架构,而是从转储文件中加载架构。
- 支持指定事务隔离级别 (提交) - 选择可重复读取或更高的性能(更少的锁定)哪个更重要。
- Dalli (提交) - 使用 Dalli memcache 客户端作为 memcache 存储。
- 通知启动和结束 (提交) - Active Support 检测报告启动和结束通知给订阅者。
- 默认情况下线程安全 (提交) - Rails 可以在不进行任何额外配置的情况下在线程化应用程序服务器中运行。
检查您正在使用的 gem 是否线程安全。
- PATCH 动词 (提交) - 在 Rails 中,PATCH 替换 PUT。PATCH 用于对资源进行部分更新。
3.4 安全性
- match 不捕获所有内容 (提交) - 在路由 DSL 中,match 需要指定 HTTP 动词。
- 默认情况下对 html 实体进行转义 (提交) - 除非使用
raw
包装或调用html_safe
,否则在 erb 中渲染的字符串将被转义。 - 新的安全标头 (提交) - Rails 在每个 HTTP 请求中发送以下标头:
X-Frame-Options
(通过禁止浏览器将页面嵌入框架来防止点击劫持)、X-XSS-Protection
(要求浏览器停止脚本注入)和X-Content-Type-Options
(防止浏览器将 jpeg 打开为 exe)。
4 将功能提取到 gem
在 Rails 4.0 中,一些功能已被提取到 gem 中。您只需将提取的 gem 添加到您的 Gemfile
中即可恢复功能。
- 基于哈希和动态查找方法 (GitHub)
- Active Record 模型中的批量分配保护 (GitHub,拉取请求)
- ActiveRecord::SessionStore (GitHub,拉取请求)
- Active Record 观察者 (GitHub,提交)
- Active Resource (GitHub,Pull Request,博客)
- Action 缓存 (GitHub,Pull Request)
- 页面缓存 (GitHub,Pull Request)
- Sprockets (GitHub)
- 性能测试 (GitHub,Pull Request)
5 文档
指南已重写为 GitHub Flavored Markdown。
指南具有响应式设计。
6 Railties
有关详细更改,请参阅 变更日志。
6.1 显著变化
新的测试位置
test/models
、test/helpers
、test/controllers
和test/mailers
。相应的 rake 任务也已添加。 (Pull Request)您的应用程序可执行文件现在位于
bin/
目录中。运行rake rails:update:bin
获取bin/bundle
、bin/rails
和bin/rake
。默认情况下启用线程安全
通过将
--builder
(或-b
)传递给rails new
来使用自定义构建器的功能已被删除。请考虑改用应用程序模板。 (Pull Request)
6.2 弃用
config.threadsafe!
已弃用,取而代之的是config.eager_load
,它对要急切加载的内容提供了更细粒度的控制。Rails::Plugin
已不再存在。不要将插件添加到vendor/plugins
中,而是使用 gem 或 bundler 以及路径或 git 依赖项。
7 Action Mailer
有关详细更改,请参阅 变更日志。
7.1 显著变化
7.2 弃用
8 Active Model
有关详细更改,请参阅 变更日志。
8.1 显著变化
添加
ActiveModel::ForbiddenAttributesProtection
,这是一个简单模块,用于在传递了未允许的属性时保护属性免受批量赋值。添加了
ActiveModel::Model
,这是一个混合类,可以使 Ruby 对象开箱即用地与 Action Pack 配合使用。
8.2 弃用
9 Active Support
有关详细更改,请参阅 变更日志。
9.1 显著变化
在
ActiveSupport::Cache::MemCacheStore
中用dalli
替换已弃用的memcache-client
gem。优化
ActiveSupport::Cache::Entry
以减少内存和处理开销。现在可以根据语言环境定义词语变化。
singularize
和pluralize
接受语言环境作为额外参数。如果接收对象未实现该方法,则
Object#try
现在将返回 nil 而不是引发 NoMethodError,但您仍然可以使用新的Object#try!
来获取旧的行为。当给出无效日期时,
String#to_date
现在会引发ArgumentError: invalid date
而不是NoMethodError: undefined method 'div' for nil:NilClass
。它现在与Date.parse
相同,并且它接受比 3.x 更多的无效日期,例如# ActiveSupport 3.x "asdf".to_date # => NoMethodError: undefined method `div' for nil:NilClass "333".to_date # => NoMethodError: undefined method `div' for nil:NilClass # ActiveSupport 4 "asdf".to_date # => ArgumentError: invalid date "333".to_date # => Fri, 29 Nov 2013
9.2 弃用
弃用
ActiveSupport::TestCase#pending
方法,改用 minitest 中的skip
。ActiveSupport::Benchmarkable#silence
由于缺乏线程安全而被弃用。它将在 Rails 4.1 中被移除,不会提供替代方案。ActiveSupport::JSON::Variable
已弃用。为自定义 JSON 字符串文字定义您自己的#as_json
和#encode_json
方法。弃用兼容性方法
Module#local_constant_names
,改用Module#local_constants
(它返回符号)。ActiveSupport::BufferedLogger
已弃用。请使用ActiveSupport::Logger
或 Ruby 标准库中的日志记录器。弃用
assert_present
和assert_blank
,改用assert object.blank?
和assert object.present?
10 Action Pack
有关详细更改,请参阅 变更日志。
10.1 显著变化
- 更改开发模式下异常页面的样式表。此外,在所有异常页面中,还显示导致异常的代码行和片段。
10.2 弃用
11 Active Record
有关详细更改,请参阅 变更日志。
11.1 显著变化
改进编写
change
迁移的方式,不再需要旧的up
和down
方法。添加了 PostgreSQL 数组类型支持。任何数据类型都可以用来创建数组列,并提供完整的迁移和架构转储支持。
添加
Relation#load
以显式加载记录并返回self
。Model.all
现在返回ActiveRecord::Relation
,而不是记录数组。如果您真的想要数组,请使用Relation#to_a
。在某些特定情况下,这可能会在升级时导致中断。添加了
ActiveRecord::Migration.check_pending!
,如果迁移挂起,则会引发错误。添加了
ActiveRecord::Store
的自定义编码器支持。现在您可以这样设置自定义编码器store :settings, accessors: [ :color, :homepage ], coder: JSON
mysql
和mysql2
连接默认情况下将设置SQL_MODE=STRICT_ALL_TABLES
以避免静默数据丢失。这可以通过在您的database.yml
中指定strict: false
来禁用。移除 IdentityMap。
移除自动执行 EXPLAIN 查询。
active_record.auto_explain_threshold_in_seconds
选项不再使用,应予以删除。添加了
ActiveRecord::NullRelation
和ActiveRecord::Relation#none
,它们为 Relation 类实现了空对象模式。添加了
create_join_table
迁移帮助器以创建 HABTM 联接表。允许创建 PostgreSQL hstore 记录。
11.2 弃用
弃用了旧式的基于哈希的查找器 API。这意味着以前接受“查找器选项”的方法现在不再接受。
除
find_by_...
和find_by_...!
外的所有动态方法均已弃用。以下是如何重写代码的方法find_all_by_...
可以使用where(...)
重写。find_last_by_...
可以使用where(...).last
重写。scoped_by_...
可以使用where(...)
重写。find_or_initialize_by_...
可以使用find_or_initialize_by(...)
重写。find_or_create_by_...
可以使用find_or_create_by(...)
重写。find_or_create_by_...!
可以使用find_or_create_by!(...)
重写。
12 致谢
请参阅 Rails 的完整贡献者列表,了解为使 Rails 成为稳定而强大的框架而花费了大量时间的人们。感谢所有贡献者。