1 升级到 Rails 5.1
如果您要升级现有应用程序,建议您在开始之前拥有良好的测试覆盖率。您还应该先升级到 Rails 5.0(如果您尚未升级),并确保应用程序在尝试升级到 Rails 5.1 之前按预期运行。有关升级时需要注意的事项,请参阅 升级 Ruby on Rails 指南。
2 主要功能
2.1 Yarn 支持
Rails 5.1 允许通过 Yarn 从 npm 管理 JavaScript 依赖项。这将使使用来自 npm 世界的库(如 React、VueJS 或任何其他库)变得容易。Yarn 支持已集成到资产管道中,因此所有依赖项都将与 Rails 5.1 应用程序无缝协作。
2.2 可选 Webpack 支持
Rails 应用程序可以使用新的 Webpacker gem 更轻松地与 JavaScript 资产捆绑程序 Webpack 集成。在生成新应用程序时使用 --webpack
标志可启用 Webpack 集成。
这与资产管道完全兼容,您可以继续使用资产管道来管理图像、字体、声音和其他资产。您甚至可以将一些 JavaScript 代码由资产管道管理,而其他代码则通过 Webpack 处理。所有这些都由 Yarn 管理,默认情况下启用 Yarn。
2.3 jQuery 不再是默认依赖项
在早期版本的 Rails 中,jQuery 是默认要求的,以提供诸如 data-remote
、data-confirm
和 Rails 非侵入式 JavaScript 提供的其他功能。现在不再需要它,因为 UJS 已重写为使用纯原生 JavaScript。此代码现在作为 rails-ujs
随 Action View 一起提供。
如果需要,您仍然可以使用 jQuery,但它不再是默认要求的。
2.4 系统测试
Rails 5.1 内置了编写 Capybara 测试的支持,以系统测试的形式。您不再需要担心为这类测试配置 Capybara 和数据库清理策略。Rails 5.1 提供了一个包装器,用于在 Chrome 中运行测试,并提供其他功能,例如失败截图。
2.5 加密的秘密
Rails 现在允许以安全的方式管理应用程序秘密,灵感来自 sekrets gem。
运行 bin/rails secrets:setup
以设置新的加密秘密文件。这还将生成一个主密钥,该密钥必须存储在存储库之外。然后,秘密本身可以以加密的形式安全地签入版本控制系统。
秘密将在生产环境中解密,使用存储在 RAILS_MASTER_KEY
环境变量或密钥文件中的密钥。
2.6 参数化邮件器
允许指定在邮件器类中所有方法中使用的通用参数,以便共享实例变量、标头和其他通用设置。
class InvitationsMailer < ApplicationMailer
before_action { @inviter, @invitee = params[:inviter], params[:invitee] }
before_action { @account = params[:inviter].account }
def account_invitation
mail subject: "#{@inviter.name} invited you to their Basecamp (#{@account.name})"
end
end
InvitationsMailer.with(inviter: person_a, invitee: person_b)
.account_invitation.deliver_later
2.7 直接和解析的路由
Rails 5.1 在路由 DSL 中添加了两个新方法 resolve
和 direct
。resolve
方法允许自定义模型的多态映射。
resource :basket
resolve("Basket") { [:basket] }
<%= form_for @basket do |form| %>
<!-- basket form -->
<% end %>
这将生成单数 URL /basket
,而不是通常的 /baskets/:id
。
direct
方法允许创建自定义 URL 助手。
direct(:homepage) { "https://rubyonrails.net.cn" }
homepage_url # => "https://rubyonrails.net.cn"
块的返回值必须是 url_for
方法的有效参数。因此,您可以传递有效的字符串 URL、哈希、数组、Active Model 实例或 Active Model 类。
direct :commentable do |model|
[ model, anchor: model.dom_id ]
end
direct :main do
{ controller: 'pages', action: 'index', subdomain: 'www' }
end
2.8 将 form_for 和 form_tag 统一为 form_with
在 Rails 5.1 之前,处理 HTML 表单有两种接口:form_for
用于模型实例,form_tag
用于自定义 URL。
Rails 5.1 使用 form_with
将这两种接口结合起来,并且可以根据 URL、作用域或模型生成表单标签。
仅使用 URL
<%= form_with url: posts_path do |form| %>
<%= form.text_field :title %>
<% end %>
<%# Will generate %>
<form action="/posts" method="post" data-remote="true">
<input type="text" name="title">
</form>
添加作用域会为输入字段名称添加前缀
<%= form_with scope: :post, url: posts_path do |form| %>
<%= form.text_field :title %>
<% end %>
<%# Will generate %>
<form action="/posts" method="post" data-remote="true">
<input type="text" name="post[title]">
</form>
使用模型会推断 URL 和作用域
<%= form_with model: Post.new do |form| %>
<%= form.text_field :title %>
<% end %>
<%# Will generate %>
<form action="/posts" method="post" data-remote="true">
<input type="text" name="post[title]">
</form>
现有模型创建更新表单并填写字段值
<%= form_with model: Post.first do |form| %>
<%= form.text_field :title %>
<% end %>
<%# Will generate %>
<form action="/posts/1" method="post" data-remote="true">
<input type="hidden" name="_method" value="patch">
<input type="text" name="post[title]" value="<the title of the post>">
</form>
3 不兼容性
以下更改可能需要在升级后立即采取行动。
3.1 具有多个连接的事务性测试
事务性测试现在将所有 Active Record 连接包装在数据库事务中。
当测试生成额外的线程,并且这些线程获取数据库连接时,这些连接现在会得到特殊处理
线程将共享单个连接,该连接位于受管事务中。这确保所有线程都看到数据库处于相同状态,忽略最外层事务。以前,例如,此类其他连接无法看到夹具行。
当线程进入嵌套事务时,它将暂时获得对连接的独占使用权,以维护隔离性。
如果您的测试目前依赖于在生成的线程中获取独立的、非事务性连接,您需要切换到更明确的连接管理。
如果您的测试生成线程,并且这些线程在交互的同时也使用显式数据库事务,此更改可能会引入死锁。
退出此新行为的简单方法是在任何受其影响的测试用例上禁用事务性测试。
4 Railties
请参阅 变更日志 以了解详细的更改。
4.1 移除
删除弃用的
config.static_cache_control
。(提交)删除弃用的
config.serve_static_files
。(提交)删除弃用的文件
rails/rack/debugger
。(提交)删除弃用的任务:
rails:update
、rails:template
、rails:template:copy
、rails:update:configs
和rails:update:bin
。(提交)删除
routes
任务的弃用CONTROLLER
环境变量。(提交)从
rails new
命令中移除 -j (--javascript) 选项。(Pull Request)
4.2 重要变更
在
config/secrets.yml
中添加了一个共享部分,该部分将被所有环境加载。(commit)配置文件
config/secrets.yml
现在所有键都被加载为符号。(Pull Request)从默认堆栈中移除jquery-rails。rails-ujs,与 Action View 捆绑在一起,被包含为默认的 UJS 适配器。(Pull Request)
在新应用中使用 yarn binstub 和 package.json 添加 Yarn 支持。(Pull Request)
通过
--webpack
选项在新应用中添加 Webpack 支持,该选项将委托给 rails/webpacker gem。(Pull Request)如果未提供选项
--skip-git
,则在生成新应用时初始化 Git 仓库。(Pull Request)在
config/secrets.yml.enc
中添加加密的秘密。(Pull Request)在
rails initializers
中显示 railtie 类名。(Pull Request)
5 Action Cable
有关详细变更,请参阅Changelog。
5.1 重要变更
在
cable.yml
中为 Redis 和事件驱动型 Redis 适配器添加了对channel_prefix
的支持,以避免在将同一 Redis 服务器与多个应用程序一起使用时出现命名冲突。(Pull Request)为广播数据添加了
ActiveSupport::Notifications
钩子。(Pull Request)
6 Action Pack
有关详细变更,请参阅Changelog。
6.1 移除
移除了对
ActionDispatch::IntegrationTest
和ActionController::TestCase
类的#process
、#get
、#post
、#patch
、#put
、#delete
和#head
中的非关键字参数的支持。(Commit, Commit)移除了已弃用的
ActionDispatch::Callbacks.to_prepare
和ActionDispatch::Callbacks.to_cleanup
。(Commit)移除了与控制器过滤器相关的已弃用方法。(Commit)
移除了对在
ActionController::Parameters
上调用HashWithIndifferentAccess
方法的已弃用支持。(Commit)
6.2 弃用
- 弃用了
config.action_controller.raise_on_unfiltered_parameters
。它在 Rails 5.1 中没有效果。(Commit)
6.3 重要变更
在路由 DSL 中添加了
direct
和resolve
方法。(Pull Request)添加了一个新的
ActionDispatch::SystemTestCase
类,用于在您的应用程序中编写系统测试。(Pull Request)
7 Action View
有关详细变更,请参阅Changelog。
7.1 移除
移除了
ActionView::Template::Error
中的已弃用的#original_exception
。(commit)从
strip_tags
中移除选项encode_special_chars
的误称。(Pull Request)
7.2 弃用
- 弃用了 Erubis ERB 处理程序,转而使用 Erubi。(Pull Request)
7.3 重要变更
原始模板处理程序(Rails 5 中的默认模板处理程序)现在输出 HTML 安全字符串。(commit)
将
datetime_field
和datetime_field_tag
更改为生成datetime-local
字段。(Pull Request)HTML 标签的新 Builder 风格语法(
tag.div
、tag.br
等)。(Pull Request)添加
form_with
以统一form_tag
和form_for
的使用。(Pull Request)为
current_page?
添加check_parameters
选项。(Pull Request)
8 Action Mailer
有关详细变更,请参阅Changelog。
8.1 重要变更
允许在包含附件和正文内联的情况下设置自定义内容类型。(Pull Request)
允许将 lambda 传递给
default
方法作为值。(Commit)添加了对邮件程序参数化调用的支持,以在不同的邮件程序操作之间共享前置过滤器和默认值。(Commit)
将传入参数传递给邮件程序操作,以在
args
键下传递给process.action_mailer
事件。(Pull Request)
9 Active Record
有关详细变更,请参阅Changelog。
9.1 移除
移除了对同时将参数和块传递给
ActiveRecord::QueryMethods#select
的支持。(Commit)移除了已弃用的
activerecord.errors.messages.restrict_dependent_destroy.one
和activerecord.errors.messages.restrict_dependent_destroy.many
i18n 范围。(Commit)移除了单数和集合关联读取器中已弃用的强制重新加载参数。(Commit)
移除了对将列传递给
#quote
的已弃用支持。(Commit)移除了
#tables
中已弃用的name
参数。(Commit)移除了
#tables
和#table_exists?
的已弃用行为,即返回表和视图,以仅返回表,而不是视图。(Commit)移除了
ActiveRecord::StatementInvalid#initialize
和ActiveRecord::StatementInvalid#original_exception
中已弃用的original_exception
参数。(Commit)移除了在查询中将类作为值传递的已弃用支持。(Commit)
移除了对使用逗号在 LIMIT 上进行查询的已弃用支持。(Commit)
移除了
#destroy_all
中已弃用的conditions
参数。(Commit)移除了
#delete_all
中已弃用的conditions
参数。(Commit)移除了已弃用的
#load_schema_for
方法,转而使用#load_schema
。(Commit)移除了已弃用的
#raise_in_transactional_callbacks
配置。(Commit)移除了已弃用的
#use_transactional_fixtures
配置。(Commit)
9.2 弃用
弃用了
error_on_ignored_order_or_limit
标志,转而使用error_on_ignored_order
。(Commit)弃用了
sanitize_conditions
,转而使用sanitize_sql
。(Pull Request)弃用了连接适配器上的
supports_migrations?
。(Pull Request)弃用了
Migrator.schema_migrations_table_name
,请改用SchemaMigration.table_name
。(Pull Request)弃用了在引用和类型转换中使用
#quoted_id
。(Pull Request)弃用了将
default
参数传递给#index_name_exists?
。(Pull Request)
9.3 重要变更
将默认主键更改为 BIGINT。(Pull Request)
对 MySQL 5.7.5+ 和 MariaDB 5.2.0+ 添加了虚拟/生成列支持。(Commit)
添加了对批处理中限制的支持。(Commit)
事务测试现在将所有 Active Record 连接包装在数据库事务中。(Pull Request)
默认情况下跳过了
mysqldump
命令输出中的注释。(Pull Request)修复了
ActiveRecord::Relation#count
,以便在传递块作为参数而不是静默忽略传递的块时,使用 Ruby 的Enumerable#count
来计数记录。(Pull Request)使用
psql
命令传递"-v ON_ERROR_STOP=1"
标志,以不抑制 SQL 错误。(Pull Request)添加
ActiveRecord::Base.connection_pool.stat
。(Pull Request)直接从
ActiveRecord::Migration
继承会引发错误。请指定为其编写迁移的 Rails 版本。(Commit)当
through
关联具有模糊的反射名称时,会引发错误。(Commit)
10 Active Model
有关详细变更,请参阅Changelog。
10.1 移除
移除了
ActiveModel::Errors
中已弃用的方法。(commit)移除了长度验证器中已弃用的
:tokenizer
选项。(commit)移除了已弃用的行为,该行为在返回值为 false 时会停止回调。(commit)
10.2 重要变更
- 分配给模型属性的原始字符串不再被错误地冻结。(Pull Request)
11 Active Job
有关详细变更,请参阅Changelog。
11.1 移除
移除了对将适配器类传递给
.queue_adapter
的已弃用支持。(commit)移除了
ActiveJob::DeserializationError
中已弃用的#original_exception
。(commit)
11.2 重要变更
通过
ActiveJob::Base.retry_on
和ActiveJob::Base.discard_on
添加了声明式异常处理。(Pull Request)生成作业实例,以便您可以在重试失败后的自定义逻辑中访问诸如
job.arguments
之类的内容。(commit)
12 Active Support
有关详细变更,请参阅Changelog。
12.1 移除
移除了
ActiveSupport::Concurrency::Latch
类。(Commit)移除了
halt_callback_chains_on_return_false
。(Commit)移除了已弃用的行为,该行为在返回值为 false 时会停止回调。(commit)
12.2 弃用
顶级
HashWithIndifferentAccess
类已被软弃用,转而使用ActiveSupport::HashWithIndifferentAccess
类。(Pull Request)弃用了将字符串传递给
:if
和:unless
条件选项,这些选项在set_callback
和skip_callback
上。(Commit)
12.3 重要变更
将 Unicode 更新至版本 9.0.0。 (拉取请求)
添加 Duration#before 和 #after 作为 #ago 和 #since 的别名。 (拉取请求)
添加了
Module#delegate_missing_to
,用于将未为当前对象定义的方法调用委托给代理对象。 (拉取请求)添加了
Date#all_day
,它返回一个范围,代表当前日期和时间的整个日期。 (拉取请求)为测试引入了
assert_changes
和assert_no_changes
方法。 (拉取请求)travel
和travel_to
方法现在在嵌套调用时抛出异常。 (拉取请求)更新
DateTime#change
以支持 usec 和 nsec。 (拉取请求)
13 贡献者
查看 Rails 贡献者完整列表,了解那些花费数小时时间让 Rails 成为一个稳定可靠框架的人们。向他们致敬。