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。
更多信息: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 中,提取公共子路由(
/posts/1/comments和/videos/1/comments中的comments)。 - ActionController::Live (提交) - 使用
response.stream流式传输 JSON。 - 声明式 ETag (提交) - 添加控制器级别的 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 (提交) - 作用域必须始终使用可调用对象。
- Schema 缓存转储 (提交) - 为了提高 Rails 启动时间,不再直接从数据库加载 schema,而是从转储文件加载 schema。
- 支持指定事务隔离级别 (提交) - 选择重复读还是改进性能(减少锁定)更重要。
- Dalli (提交) - 将 Dalli memcache 客户端用于 memcache 存储。
- 通知开始和结束 (提交) - Active Support 仪表报告开始和结束通知给订阅者。
- 默认线程安全 (提交) - Rails 可以在线程化应用服务器中运行,无需额外配置。
检查您正在使用的 gem 是否线程安全。
- PATCH 动词 (提交) - 在 Rails 中,PATCH 替换 PUT。PATCH 用于资源的局部更新。
3.4. 安全性
- match 不再捕获所有 (提交) - 在路由 DSL 中,match 要求指定 HTTP 动词。
- HTML 实体默认转义 (提交) - 在 erb 中渲染的字符串会被转义,除非使用
raw包裹或调用html_safe。 - 新的安全头 (提交) - 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, Pull Request)
- ActiveRecord::SessionStore (GitHub, Pull Request)
- Active Record Observers (GitHub, 提交)
- Active Resource (GitHub, Pull Request, 博客)
- Action Caching (GitHub, Pull Request)
- Page Caching (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。默认开启线程安全
通过向
rails new传递--builder(或-b)来使用自定义构建器的功能已移除。请考虑使用应用程序模板代替。 (Pull Request)
6.2. 弃用
config.threadsafe!已弃用,取而代之的是config.eager_load,它提供了对预加载内容的更细粒度控制。Rails::Plugin已移除。不再将插件添加到vendor/plugins,而是使用 gem 或带路径或 git 依赖项的 bundler。
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-clientgem。优化
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 数组类型支持。任何数据类型都可以用于创建数组列,并提供完整的迁移和 schema dumper 支持。
添加
Relation#load以显式加载记录并返回self。Model.all现在返回一个ActiveRecord::Relation,而不是记录数组。如果您确实需要一个数组,请使用Relation#to_a。在某些特定情况下,这可能会在升级时导致问题。添加了
ActiveRecord::Migration.check_pending!,如果存在待处理的迁移,则会引发错误。添加了对
ActiveRecord::Store的自定义编码器支持。现在您可以像这样设置您的自定义编码器store :settings, accessors: [ :color, :homepage ], coder: JSONmysql和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 成为一个稳定而健壮的框架。向他们所有人致敬。
