1 升级到 Rails 5.2
如果您要升级现有应用程序,建议您在进行升级之前先进行良好的测试覆盖。您还应该先升级到 Rails 5.1(如果您还没有升级),并确保您的应用程序在尝试升级到 Rails 5.2 之前按预期运行。在 升级 Ruby on Rails 指南中可以找到升级时需要注意的事项列表。
2 主要功能
2.1 Active Storage
Active Storage 能够将文件上传到云存储服务,例如 Amazon S3、Google Cloud Storage 或 Microsoft Azure Storage,并将这些文件附加到 Active Record 对象。它带有一个用于开发和测试的本地磁盘服务,并支持将文件镜像到子服务以进行备份和迁移。您可以在 Active Storage 概述 指南中阅读有关 Active Storage 的更多信息。
2.2 Redis 缓存存储
Rails 5.2 附带内置的 Redis 缓存存储。您可以在 使用 Rails 进行缓存:概述 指南中阅读有关此内容的更多信息。
2.3 HTTP/2 早期提示
Rails 5.2 支持 HTTP/2 早期提示。要使用启用早期提示的服务器启动服务器,请将 --early-hints
传递给 bin/rails server
。
2.4 凭据
添加了 config/credentials.yml.enc
文件以存储生产应用程序机密。它允许使用 config/master.key
文件中的密钥或 RAILS_MASTER_KEY
环境变量加密的密钥,直接在存储库中保存任何针对第三方服务的身份验证凭据。这最终将取代 Rails.application.secrets
以及在 Rails 5.1 中引入的加密机密。此外,Rails 5.2 开放了 Credentials 底层 API,因此您可以轻松地处理其他加密配置、密钥和文件。您可以在 保护 Rails 应用程序 指南中阅读有关此内容的更多信息。
2.5 内容安全策略
Rails 5.2 附带一个新的 DSL,允许您为您的应用程序配置 内容安全策略。您可以配置全局默认策略,然后在每个资源的基础上覆盖它,甚至可以使用 lambda 将每个请求的值注入标头,例如多租户应用程序中的帐户子域。您可以在 保护 Rails 应用程序 指南中阅读有关此内容的更多信息。
3 Railties
请参阅 变更日志 以了解详细的更改。
3.1 弃用
弃用生成器和模板中的
capify!
方法。(拉取请求)将环境名称作为常规参数传递给
rails dbconsole
和rails console
命令已被弃用。应使用-e
选项。(提交)弃用使用
Rails::Application
的子类来启动 Rails 服务器。(拉取请求)弃用 Rails 插件模板中的
after_bundle
回调。(拉取请求)
3.2 显著变化
在
config/database.yml
中添加了一个共享部分,该部分将为所有环境加载。(拉取请求)将
railtie.rb
添加到插件生成器。(拉取请求)在
tmp:clear
任务中清除屏幕截图文件。(拉取请求)在运行
bin/rails app:update
时跳过未使用的组件。如果初始应用程序生成跳过了 Action Cable、Active Record 等,更新任务也会尊重这些跳过。(拉取请求)允许在使用三级数据库配置时将自定义连接名称传递给
rails dbconsole
命令。例如:bin/rails dbconsole -c replica
。(提交)正确扩展运行
console
和dbconsole
命令的环境名称的快捷方式。(提交)将
bootsnap
添加到默认的Gemfile
中。(拉取请求)支持使用
-
作为平台无关的方式,使用rails runner
从 stdin 运行脚本 (拉取请求)在创建新的 Rails 应用程序时,将
ruby x.x.x
版本添加到Gemfile
,并创建包含当前 Ruby 版本的根目录.ruby-version
文件。(拉取请求)将
--skip-action-cable
选项添加到插件生成器。(拉取请求)将
git_source
添加到插件生成器的Gemfile
中。(拉取请求)在 Rails 插件中运行
bin/rails
时跳过未使用的组件。(提交)优化生成器操作的缩进。(拉取请求)
优化路由缩进。(拉取请求)
将
--skip-yarn
选项添加到插件生成器。(拉取请求)支持生成器的
gem
方法的多个版本参数。(拉取请求)在开发和测试环境中从应用程序名称推断出
secret_key_base
。(拉取请求)将
mini_magick
添加到默认的Gemfile
中作为注释。(拉取请求)rails new
和rails plugin new
默认情况下获得Active Storage
。添加了使用--skip-active-storage
跳过Active Storage
的功能,并在使用--skip-active-record
时自动执行此操作。(拉取请求)
4 Action Cable
请参阅 变更日志 以了解详细的更改。
4.1 移除
- 删除了已弃用的事件 redis 适配器。(提交)
4.2 显著变化
5 Action Pack
请参阅 变更日志 以了解详细的更改。
5.1 移除
- 删除了已弃用的
ActionController::ParamsParser::ParseError
。(提交)
5.2 弃用
- 弃用
ActionDispatch::TestResponse
的#success?
、#missing?
和#error?
别名。(拉取请求)
5.3 显著变化
添加了对使用片段缓存的可回收缓存键的支持。(拉取请求)
更改了片段的缓存键格式,使其更容易调试键周转。(拉取请求)
使用 GCM 对 AEAD 加密的 cookie 和会话进行加密。(拉取请求)
默认情况下防止跨站请求伪造。(拉取请求)
在服务器端强制执行已签署/已加密的 cookie 过期。(拉取请求)
cookie 的
:expires
选项支持ActiveSupport::Duration
对象。(拉取请求)使用 Capybara 注册的
:puma
服务器配置。(拉取请求)使用密钥轮换支持简化 cookie 中间件。(拉取请求)
添加了为 HTTP/2 启用早期提示的功能。(拉取请求)
为系统测试添加无头 Chrome 支持。(Pull Request)
在
redirect_back
方法中添加:allow_other_host
选项。(Pull Request)使
assert_recognizes
可以遍历挂载的引擎。(Pull Request)添加 DSL 用于配置 Content-Security-Policy 标头。(Pull Request, Commit, Commit)
注册现代浏览器支持的最流行的音频/视频/字体 MIME 类型。(Pull Request)
将系统测试的默认截图输出从
inline
更改为simple
。(Commit)为系统测试添加无头 Firefox 支持。(Pull Request)
将安全的
X-Download-Options
和X-Permitted-Cross-Domain-Policies
添加到默认的标头集中。(Commit)更改系统测试,仅当用户未手动指定其他服务器时才将 Puma 作为默认服务器。(Pull Request)
将
Referrer-Policy
标头添加到默认的标头集中。(Commit)匹配
ActionController::Parameters#each
中Hash#each
的行为。(Pull Request)添加对 Rails UJS 自动 nonce 生成的支持。(Commit)
将默认的 HSTS max-age 值更新为 31536000 秒(1 年),以满足 https://hstspreload.org/ 的最小 max-age 要求。(Commit)
为
cookies
添加别名方法to_hash
到to_h
。为session
添加别名方法to_h
到to_hash
。(Commit)
6 Action View
有关详细更改,请参阅 Changelog。
6.1 删除
- 删除已弃用的 Erubis ERB 处理程序。(Commit)
6.2 弃用
- 弃用
image_alt
助手,该助手用于为image_tag
生成的图像添加默认的 alt 文本。(Pull Request)
6.3 重要更改
将
:json
类型添加到auto_discovery_link_tag
以支持 JSON Feeds。(Pull Request)在
image_tag
助手添加srcset
选项。(Pull Request)修复了
field_error_proc
包裹optgroup
和选择分隔符option
的问题。(Pull Request)更改
form_with
以默认生成 ID。(Commit)添加
preload_link_tag
助手。(Pull Request)允许使用可调用对象作为分组选择的组方法。(Pull Request)
7 Action Mailer
有关详细更改,请参阅 Changelog。
7.1 重要更改
允许 Action Mailer 类配置其传递作业。(Pull Request)
添加
assert_enqueued_email_with
测试助手。(Pull Request)
8 Active Record
有关详细更改,请参阅 Changelog。
8.1 删除
删除已弃用的
#migration_keys
。(Pull Request)删除在类型转换 Active Record 对象时对
quoted_id
的已弃用支持。(Commit)删除从
index_name_exists?
中已弃用的参数default
。(Commit)删除对关联中将类传递给
:class_name
的已弃用支持。(Commit)删除已弃用的方法
initialize_schema_migrations_table
和initialize_internal_metadata_table
。(Commit)删除已弃用的方法
supports_migrations?
。(Commit)删除已弃用的方法
supports_primary_key?
。(Commit)删除已弃用的方法
ActiveRecord::Migrator.schema_migrations_table_name
。(Commit)删除从
#indexes
中已弃用的参数name
。(Commit)删除从
#verify!
中已弃用的参数。(Commit)删除已弃用的配置
.error_on_ignored_order_or_limit
。(Commit)删除已弃用的方法
#scope_chain
。(Commit)删除已弃用的方法
#sanitize_conditions
。(Commit)
8.2 弃用
弃用
supports_statement_cache?
。(Pull Request)弃用在
ActiveRecord::Calculations
中同时将参数和块传递给count
和sum
。(Pull Request)弃用在
Relation
中委派给arel
。(Pull Request)弃用
TransactionState
中的set_state
方法。(Commit)弃用
expand_hash_conditions_for_aggregates
,没有替代品。(Commit)
8.3 重要更改
当使用没有参数的动态固定装置访问器方法调用时,它现在将返回此类型的所有固定装置。以前,此方法始终返回一个空数组。(Pull Request)
修复了在覆盖 Active Record 属性阅读器时更改属性不一致的问题。(Pull Request)
支持 MySQL 的降序索引。(Pull Request)
修复
bin/rails db:forward
的第一个迁移。(Commit)在当前迁移不存在时,在迁移移动时引发错误
UnknownMigrationVersionError
。(Commit)在用于数据库结构转储的 rake 任务中,在
SchemaDumper.ignore_tables
中尊重。(Pull Request)添加
ActiveRecord::Base#cache_version
以通过ActiveSupport::Cache
中的新版本化条目支持可回收的缓存键。这也意味着ActiveRecord::Base#cache_key
现在将返回一个稳定的键,不再包含时间戳。(Pull Request)防止在转换后的值为 nil 时创建绑定参数。(Pull Request)
使用批量 INSERT 插入固定装置,以提高性能。(Pull Request)
合并表示嵌套联接的两个关系不再将合并关系的联接转换为 LEFT OUTER JOIN。(Pull Request)
修复事务以将状态应用于子事务。以前,如果您有嵌套事务并且外部事务回滚,则内部事务的记录仍将标记为已持久化。通过在父事务回滚时将父事务的状态应用于子事务来修复此问题。这将正确地将内部事务的记录标记为未持久化。(Commit)
修复包含联接的范围的急切加载/预加载关联。(Pull Request)
防止
sql.active_record
通知订阅者引发的错误被转换为ActiveRecord::StatementInvalid
异常。(Pull Request)在处理记录批次(
find_each
、find_in_batches
、in_batches
)时,跳过查询缓存。(Commit)将 sqlite3 布尔序列化更改为使用 1 和 0。SQLite 本机识别 1 和 0 作为真和假,但不像以前序列化的那样,SQLite 本机不识别 't' 和 'f'。(Pull Request)
使用多参数赋值构造的值现在将在单字段表单输入中使用类型转换后的值进行呈现。(Commit)
生成模型时不再生成
ApplicationRecord
。如果您需要生成它,可以使用rails g application_record
来创建它。(Pull Request)Relation#or
现在接受两个关系,这些关系只有references
的值不同,因为references
可以由where
隐式调用。(Commit)在使用
Relation#or
时,提取公共条件并将它们放在 OR 条件之前。(Pull Request)添加
binary
固定装置助手方法。(Pull Request)自动猜测 STI 的反向关联。(Pull Request)
添加新的错误类
LockWaitTimeout
,它将在锁等待超时时引发。(Pull Request)更新
sql.active_record
检测的有效载荷名称,使其更具描述性。(Pull Request)在从数据库中删除索引时使用给定的算法。(Pull Request)
将
Set
传递给Relation#where
的行为现在与传递数组的行为相同。(Commit)PostgreSQL
tsrange
现在保留亚秒精度。(Pull Request)在脏记录中调用
lock!
时引发异常。(Commit)修复了使用 SQLite 适配器时,索引的列顺序未写入
db/schema.rb
的错误。(Pull Request)修复
bin/rails db:migrate
与指定的VERSION
结合使用。bin/rails db:migrate
且 VERSION 为空,行为与不带VERSION
相同。检查VERSION
的格式:允许迁移版本号或迁移文件的名称。如果VERSION
的格式无效,则引发错误。如果目标迁移不存在,则引发错误。(Pull Request)添加新的错误类
StatementTimeout
,它将在语句超时时引发。(Pull Request)update_all
现在将在传递给Type#serialize
之前,将它的值传递给Type#cast
。这意味着update_all(foo: 'true')
将正确地持久化布尔值。(Commit)为数据库迁移添加
#up_only
,用于仅在向上迁移时相关的代码,例如填充新列。(Pull Request)添加新的错误类
QueryCanceled
,它将在因用户请求而取消语句时引发。(Pull Request)不允许定义与
Relation
上的实例方法冲突的范围。(Pull Request)添加对
add_index
的 PostgreSQL 运算符类的支持。(Pull Request)记录数据库查询调用者。(Pull Request, Pull Request, Pull Request)
重置列信息时,取消定义后代上的属性方法。 (Pull Request)
使用子查询进行 `delete_all` 操作,并带有 `limit` 或 `offset`。 (Commit)
修复了在使用 `limit()` 时 `first(n)` 的不一致性问题。`first(n)` 查找器现在会尊重 `limit()`,使其与 `relation.to_a.first(n)` 一致,同时也与 `last(n)` 的行为一致。 (Pull Request)
修复了未持久化的父实例上嵌套 `has_many :through` 关联的问题。 (Commit)
在删除 `through` 记录时,考虑关联条件。 (Commit)
在调用 `save` 或 `save!` 之后,不允许对已销毁的对象进行修改。 (Commit)
修复了 `left_outer_joins` 与关联合并的问题。 (Pull Request)
支持 PostgreSQL 外部表。 (Pull Request)
在克隆 Active Record 对象时,清除事务状态。 (Pull Request)
修复了使用 `composed_of` 列将数组对象作为参数传递给 `where` 方法时,未扩展的问题。 (Pull Request)
如果 `polymorphic?` 为真,则使 `reflection.klass` 抛出异常,以防止误用。 (Commit)
修复了 MySQL 和 PostgreSQL 的 `#columns_for_distinct`,使 `ActiveRecord::FinderMethods#limited_ids_for` 即使在 `ORDER BY` 列包含其他表的 primary key 时也能使用正确的 primary key 值。 (Commit)
修复了 `dependent: :destroy` 在 `has_one/belongs_to` 关系中存在的问题,其中父类在子类不存在时也被删除了。 (Commit)
空闲数据库连接(以前只是孤立连接)现在由连接池收集器定期回收。 (Commit)
9 Active Model
有关详细更改,请参阅 Changelog。
9.1 值得注意的更改
修复了 `ActiveModel::Errors` 中的 `#keys` 和 `#values` 方法。将 `#keys` 更改为仅返回不包含空消息的键。将 `#values` 更改为仅返回非空值。 (Pull Request)
为 `ActiveModel::Errors` 添加了 `#merge!` 方法。 (Pull Request)
允许将 Proc 或 Symbol 传递给长度验证器选项。 (Pull Request)
在 `_confirmation` 的值为 `false` 时执行 `ConfirmationValidator` 验证。 (Pull Request)
使用属性 API 且具有 proc 默认值的模型现在可以被序列化。 (Commit)
在序列化时不会丢失所有带选项的多个 `:includes`。 (Commit)
10 Active Support
有关详细更改,请参阅 Changelog。
10.1 删除
删除了回调中弃用的 `:if` 和 `:unless` 字符串过滤器。 (Commit)
删除了弃用的 `halt_callback_chains_on_return_false` 选项。 (Commit)
10.2 弃用
弃用 `Module#reachable?` 方法。 (Pull Request)
弃用 `secrets.secret_token`。 (Commit)
10.3 值得注意的更改
为 `HashWithIndifferentAccess` 添加了 `fetch_values`。 (Pull Request)
为 `Time#change` 添加了 `:offset` 支持。 (Commit)
为 `ActiveSupport::TimeWithZone#change` 添加了 `:offset` 和 `:zone` 支持。 (Commit)
将 gem 名称和弃用期限传递给弃用通知。 (Pull Request)
添加了对版本化缓存条目的支持。这使缓存存储能够回收缓存键,在频繁变化的情况下极大地节省了存储空间。与 Active Record 中 `#cache_key` 和 `#cache_version` 的分离以及它们在 Action Pack 的片段缓存中的使用相结合。 (Pull Request)
添加了 `ActiveSupport::CurrentAttributes` 来提供一个线程隔离的属性单例。主要用例是将所有针对每个请求的属性轻松地提供给整个系统。 (Pull Request)
`#singularize` 和 `#pluralize` 现在会针对指定区域设置尊重不可数词。 (Commit)
为 `class_attribute` 添加了默认选项。 (Pull Request)
添加了 `Date#prev_occurring` 和 `Date#next_occurring`,用于返回指定的下一个/上一个出现的星期几。 (Pull Request)
为模块和类属性访问器添加了默认选项。 (Pull Request)
缓存: `write_multi`。 (Pull Request)
将 `ActiveSupport::MessageEncryptor` 默认设置为使用 AES 256 GCM 加密。 (Pull Request)
添加了 `freeze_time` 帮助程序,它在测试中将时间冻结到 `Time.now`。 (Pull Request)
使 `Hash#reverse_merge!` 的顺序与 `HashWithIndifferentAccess` 一致。 (Pull Request)
为 `ActiveSupport::MessageVerifier` 和 `ActiveSupport::MessageEncryptor` 添加了目的和过期支持。 (Pull Request)
更新了 `String#camelize` 以在传递错误选项时提供反馈。 (Pull Request)
`Module#delegate_missing_to` 现在如果目标为 nil,则会抛出 `DelegationError`,类似于 `Module#delegate`。 (Pull Request)
添加了 `ActiveSupport::EncryptedFile` 和 `ActiveSupport::EncryptedConfiguration`。 (Pull Request)
添加了 `config/credentials.yml.enc` 来存储生产应用程序的密钥。 (Pull Request)
为 `MessageEncryptor` 和 `MessageVerifier` 添加了密钥轮换支持。 (Pull Request)
从 `HashWithIndifferentAccess#transform_keys` 返回 `HashWithIndifferentAccess` 的实例。 (Pull Request)
`Hash#slice` 现在如果定义了,则会回退到 Ruby 2.5+ 的内置定义。 (Commit)
`IO#to_json` 现在返回 `to_s` 表示,而不是尝试转换为数组。这修复了 `IO#to_json` 在不可读对象上调用时会抛出 `IOError` 的错误。 (Pull Request)
为 `Time#prev_day` 和 `Time#next_day` 添加了相同的函数签名,与 `Date#prev_day`、`Date#next_day` 相一致。允许为 `Time#prev_day` 和 `Time#next_day` 传递参数。 (Commit)
为 `Time#prev_month` 和 `Time#next_month` 添加了相同的函数签名,与 `Date#prev_month`、`Date#next_month` 相一致。允许为 `Time#prev_month` 和 `Time#next_month` 传递参数。 (Commit)
为 `Time#prev_year` 和 `Time#next_year` 添加了相同的函数签名,与 `Date#prev_year`、`Date#next_year` 相一致。允许为 `Time#prev_year` 和 `Time#next_year` 传递参数。 (Commit)
修复了 `humanize` 中的缩略词支持。 (Commit)
允许在 TWZ 范围内使用 `Range#include?`。 (Pull Request)
缓存: 为大于 1kB 的值默认启用压缩。 (Pull Request)
Redis 缓存存储。 (Pull Request, Pull Request)
处理 `TZInfo::AmbiguousTime` 错误。 (Pull Request)
MemCacheStore: 支持过期计数器。 (Commit)
使 `ActiveSupport::TimeZone.all` 仅返回 `ActiveSupport::TimeZone::MAPPING` 中的时区。 (Pull Request)
更改了 `ActiveSupport::SecurityUtils.secure_compare` 的默认行为,使其即使对于可变长度字符串也不会泄露长度信息。将旧的 `ActiveSupport::SecurityUtils.secure_compare` 重命名为 `fixed_length_secure_compare`,并在传递的字符串长度不匹配的情况下开始抛出 `ArgumentError`。 (Pull Request)
使用 SHA-1 生成不敏感的摘要,例如 ETag 标头。 (Pull Request, Pull Request)
`assert_changes` 将始终断言表达式更改,而不管 `from:` 和 `to:` 参数组合如何。 (Pull Request)
为 `ActiveSupport::Cache::Store` 中的 `read_multi` 添加了缺失的检测。 (Pull Request)
在 `assert_difference` 中支持将哈希作为第一个参数。这允许在同一个断言中指定多个数字差异。 (Pull Request)
缓存: MemCache 和 Redis `read_multi` 和 `fetch_multi` 速度提升。在咨询后端之前,先从本地内存缓存中读取。 (Commit)
11 Active Job
有关详细更改,请参阅 Changelog。
11.1 值得注意的更改
- 允许将块传递给 `ActiveJob::Base.discard_on`,以便允许自定义处理丢弃的作业。 (Pull Request)
12 Ruby on Rails 指南
有关详细更改,请参阅 Changelog。
12.1 值得注意的更改
添加了 Rails 中的线程和代码执行 指南。 (Pull Request)
添加了 Active Storage 概述 指南。 (Pull Request)
13 致谢
查看 Rails 的完整贡献者列表,以了解为 Rails 贡献了大量时间并使其成为稳定可靠框架的众多贡献者。感谢他们所有人。