更多内容请访问 rubyonrails.org:

Ruby on Rails 7.2 发行说明

Rails 7.2 的亮点

  • 应用程序的开发容器配置。
  • 默认添加浏览器版本防护。
  • 将 Ruby 3.1 设为新的最低版本。
  • 默认渐进式网络应用程序 (PWA) 文件。
  • 默认添加 omakase RuboCop 规则。
  • 默认向新应用程序添加 GitHub CI 工作流。
  • 默认向新应用程序添加 Brakeman。
  • 设置 Puma 线程计数的新默认值。
  • 防止事务内调度作业。
  • 每个事务的提交和回滚回调。
  • 如果运行 Ruby 3.3+,默认启用 YJIT。
  • Rails 指南的新设计。
  • 在默认 Dockerfile 中设置 jemalloc 以优化内存分配。
  • 在 bin/setup 中建议 puma-dev 配置。

这些发行说明仅涵盖主要变更。要了解各种错误修复和变更,请参阅变更日志或查看 GitHub 上主 Rails 仓库中的提交列表

1. 升级到 Rails 7.2

如果您正在升级现有应用程序,最好在开始之前进行良好的测试覆盖。您还应该首先升级到 Rails 7.1(如果您尚未升级)并确保您的应用程序仍按预期运行,然后再尝试更新到 Rails 7.2。在升级 Ruby on Rails 指南中提供了升级时需要注意的事项列表。

2. 主要特性

2.1. 应用程序的开发容器配置

开发容器(简称 dev container)允许您将容器用作功能齐全的开发环境。

Rails 7.2 增加了为您的应用程序生成开发容器配置的功能。此配置包括一个 .devcontainer 文件夹,其中包含一个 Dockerfile、一个 docker-compose.yml 文件和一个 devcontainer.json 文件。

默认情况下,dev container 包含以下内容

  • 一个用于 Kredis、Action Cable 等的 Redis 容器。
  • 一个数据库(SQLite、Postgres、MySQL 或 MariaDB)
  • 一个用于系统测试的无头 Chrome 容器
  • Active Storage 配置为使用本地磁盘并启用预览功能

要使用开发容器生成新应用程序,您可以运行

$ rails new myapp --devcontainer

对于现有应用程序,现在可以使用 devcontainer 命令

$ rails devcontainer

有关更多信息,请参阅Dev Containers 入门指南。

2.2. 默认添加浏览器版本防护

Rails 现在增加了指定允许访问所有操作(或部分,受 only:except: 限制)的浏览器版本的功能。

只有在传递给 versions: 的哈希或命名集合中匹配的浏览器,如果低于指定版本,才会被阻止。

这意味着所有其他未知浏览器以及未报告 user-agent 标头的代理都将被允许访问。

被阻止的浏览器默认情况下将收到 public/406-unsupported-browser.html 中的文件,HTTP 状态码为“406 Not Acceptable”。

示例

class ApplicationController < ActionController::Base
  # Allow only browsers natively supporting webp images, web push, badges, import maps, CSS nesting + :has
  allow_browser versions: :modern
end

class ApplicationController < ActionController::Base
  # All versions of Chrome and Opera will be allowed, but no versions of "internet explorer" (ie). Safari needs to be 16.4+ and Firefox 121+.
  allow_browser versions: { safari: 16.4, firefox: 121, ie: false }
end

class MessagesController < ApplicationController
  # In addition to the browsers blocked by ApplicationController, also block Opera below 104 and Chrome below 119 for the show action.
  allow_browser versions: { opera: 104, chrome: 119 }, only: :show
end

新生成的应用程序在 ApplicationController 中设置了此防护。

有关更多信息,请参阅 allow_browser 文档。

2.3. 将 Ruby 3.1 设为新的最低版本

到目前为止,Rails 只在新主要版本中放弃了对旧 Ruby 版本的兼容性。我们正在改变这一政策,因为它导致我们保持与长期不受支持的 Ruby 版本的兼容性,或者更频繁地提高 Rails 主要版本,并在提高主要版本时一次性放弃多个 Ruby 版本。

我们现在将在 Rails 次要版本发布时放弃已终止支持的 Ruby 版本。

对于 Rails 7.2,Ruby 3.1 是新的最低版本。

2.4. 默认渐进式网络应用程序 (PWA) 文件

为了更好地支持使用 Rails 创建 PWA 应用程序,我们现在为 manifest 和 service worker 生成默认的 PWA 文件,这些文件从 app/views/pwa 提供,可以通过 ERB 动态渲染。这些文件在生成的路由文件中通过默认路由显式地挂载在根目录。

有关更多信息,请参阅添加此功能的拉取请求

2.5. 默认添加 omakase RuboCop 规则

Rails 应用程序现在默认配置了 RuboCop,其中包含来自 rubocop-rails-omakase 的一组规则。

Ruby 是一种表达力极强的语言,它不仅能容忍许多不同的方言,而且还颂扬它们的多样性。它从未被设计成一种所有库、框架或应用程序都必须以单一风格编写的语言。如果您或您的团队已经形成了一种让您愉悦的特定内部风格,您应该珍惜它。

这套 RuboCop 风格适用于那些尚未采用任何特定方言的人。他们只希望有一个合理的起点,并从一些默认规则中受益,以至少开始一种一致的 Ruby 风格方法。

这些特定规则无所谓对错,它们仅仅代表了 Rails 创建者独特的审美情趣。您可以整体使用它们,也可以将其作为起点、灵感,或者以您认为合适的方式使用它们。

2.6. 默认向新应用程序添加 GitHub CI 工作流

Rails 现在默认向新应用程序添加一个 GitHub CI 工作流文件。这将使新用户能够通过自动化扫描、代码检查和测试获得良好的开端。我们认为这是我们从单元测试开始的现代化自然延续。

当然,GitHub Actions 在您用完免费令牌后,对于私有仓库来说是一种商业云产品。但考虑到 GitHub 和 Rails 之间的关系、平台对新用户的压倒性默认性质以及培养新用户良好 CI 习惯的价值,我们认为这是一个可以接受的权衡。

2.7. 默认向新应用程序添加 Brakeman

Brakeman 是防止 Rails 中常见的安全漏洞进入生产环境的好方法。

新应用程序默认安装 Brakeman,并结合 GitHub CI 工作流,它将在每次推送时自动运行。

2.8. 设置 Puma 线程计数的新默认值

Rails 将 Puma 中的默认线程数从 5 更改为 3。

由于经过良好优化的 Rails 应用程序的特性,即通过作业运行快速 SQL 查询和缓慢的第三方调用,当线程数过高时,Ruby 可能会花费大量时间等待全局 VM 锁 (GVL) 释放,这会损害延迟(请求响应时间)。

经过仔细考虑、调查以及来自生产环境中运行的应用程序的实战经验,我们决定默认 3 个线程是在并发性和性能之间取得良好平衡的。

您可以在此问题中关注有关此更改的非常详细的讨论。

2.9. 防止事务内调度作业

Active Job 的一个常见错误是在事务内部排队作业,导致它们在事务提交之前可能被其他进程选取并运行,从而导致各种错误。

Topic.transaction do
  topic = Topic.create

  NewTopicNotificationJob.perform_later(topic)
end

现在 Active Job 将自动将排队推迟到事务提交之后,如果事务回滚,则丢弃作业。

各种队列实现可以选择禁用此行为,用户可以禁用它,或者强制其按作业进行

class NewTopicNotificationJob < ApplicationJob
  self.enqueue_after_transaction_commit = :never
end

2.10. 每个事务的提交和回滚回调

这现在是可能的,因为一项新功能允许在记录之外注册事务回调。

ActiveRecord::Base.transaction 现在会生成一个 ActiveRecord::Transaction 对象,允许在其上注册回调。

Article.transaction do |transaction|
  article.update(published: true)

  transaction.after_commit do
    PublishNotificationMailer.with(article: article).deliver_later
  end
end

ActiveRecord::Base.current_transaction 也已添加,允许在其上注册回调。

Article.current_transaction.after_commit do
  PublishNotificationMailer.with(article: article).deliver_later
end

最后,添加了 ActiveRecord.after_all_transactions_commit,用于可能在事务内部或外部运行的代码,并且需要在状态更改正确持久化后执行工作。

def publish_article(article)
  article.update(published: true)

  ActiveRecord.after_all_transactions_commit do
    PublishNotificationMailer.with(article: article).deliver_later
  end
end

有关更多信息,请参阅 #51474#51426

2.11. 如果运行 Ruby 3.3+,默认启用 YJIT

YJIT 是 Ruby 的 JIT 编译器,自 Ruby 3.1 起在 CRuby 中可用。它可以为 Rails 应用程序提供显著的性能改进,提供 15-25% 的延迟改进。

在 Rails 7.2 中,如果运行 Ruby 3.3 或更高版本,YJIT 默认启用。

您可以通过设置禁用 YJIT

Rails.application.config.yjit = false

2.12. Rails 指南的新设计

Rails 7.0 于 2021 年 12 月发布时,带有一个全新的主页和新的启动屏幕。然而,指南的设计自 2009 年以来基本未变——这一点并未被忽视(我们听到了您的反馈)。

鉴于目前所有的工作都致力于消除 Rails 框架的复杂性,并使文档保持一致、清晰和最新,现在是时候着手指南的设计,使它们同样现代化、简洁和清新。

我们与用户体验设计师John Athayde合作,将主页的外观和感觉转移到 Rails 指南中,使它们干净、时尚和最新。

布局将保持不变,但从今天起,您将在指南中看到以下更改

  • 更简洁、不那么繁杂的设计。
  • 字体、配色方案和徽标与主页更一致。
  • 更新的图标。
  • 简化的导航。
  • 滚动时“章节”导航栏保持固定。

请参阅公告博客文章以查看前后对比图

2.13. 在默认 Dockerfile 中设置 jemalloc 以优化内存分配

Ruby 对 malloc 的使用可能会造成内存碎片问题,尤其是在使用多个线程时,就像 Puma 那样。切换到使用不同模式来避免碎片的分配器可以大幅减少内存使用。

Rails 7.2 现在在默认 Dockerfile 中包含 jemalloc 以优化内存分配。

2.14. 在 bin/setup 中建议 puma-dev 配置

Puma-dev 是在本地开发多个 Rails 应用程序的黄金路径,如果您不使用 Docker。

Rails 现在在 bin/setup 中您会发现的新注释中建议了如何进行此设置。

3. Railties

有关详细更改,请参阅变更日志

3.1. 移除

  • 移除已弃用的 Rails::Generators::Testing::Behaviour

  • 移除已弃用的 Rails.application.secrets

  • 移除已弃用的 Rails.config.enable_dependency_loading

  • 移除已弃用的 find_cmd_and_exec 控制台助手。

  • newdb:system:change rails 命令中移除对 oraclesqlserver 和 JRuby 特定数据库适配器的支持。

  • 从生成器中移除 config.public_file_server.enabled 选项。

3.2. 弃用

3.3. 显著变更

  • 默认在新的应用程序和插件中添加 RuboCop,并使用 rubocop-rails-omakase 中的规则。

  • 在新的应用程序中默认添加 Brakeman,并配置安全检查。

  • 默认向新的应用程序和插件添加 GitHub CI 文件,用于 Dependabot、Brakeman、RuboCop 和运行测试。

  • 对于运行 Ruby 3.3+ 的新应用程序,YJIT 现已默认启用。

  • 生成一个 .devcontainer 文件夹,用于在 Visual Studio Code 中在容器中运行应用程序。

    $ rails new myapp --devcontainer
    
  • 引入 Rails::Generators::Testing::Assertions#assert_initializer 用于测试初始化器。

  • 新的应用程序默认使用 Headless Chrome 进行系统测试。

  • 支持 BACKTRACE 环境变量,以在正常服务器运行中关闭回溯清理。以前,这仅适用于测试。

  • 添加默认的渐进式网络应用程序 (PWA) manifest 和 service worker 文件,这些文件从 app/views/pwa 提供,并使其可以通过 ERB 动态渲染。

4. Action Cable

有关详细更改,请参阅变更日志

4.1. 移除

4.2. 弃用

4.3. 显著变更

5. Action Pack

有关详细更改,请参阅变更日志

5.1. 移除

  • 移除已弃用的常量 ActionDispatch::IllegalStateError

  • 移除已弃用的常量 AbstractController::Helpers::MissingHelperError

  • 移除已弃用的 ActionController::ParametersHash 之间的比较。

  • 移除已弃用的 Rails.application.config.action_dispatch.return_only_request_media_type_on_content_type

  • 移除已弃用的 speakervibratevr 权限策略指令。

  • 移除已弃用对将 Rails.application.config.action_dispatch.show_exceptions 设置为 truefalse 的支持。

5.2. 弃用

  • 弃用 Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality

5.3. 显著变更

6. Action View

有关详细更改,请参阅变更日志

6.1. 移除

  • 移除已弃用的 @rails/ujs,转而使用 Turbo。

6.2. 弃用

  • 弃用在使用 tag.br 类型标签构建器时将内容传递给空元素。

6.3. 显著变更

7. Action Mailer

有关详细更改,请参阅变更日志

7.1. 移除

  • 移除已弃用的 config.action_mailer.preview_path

  • 移除通过 :args 传递给 assert_enqueued_email_with 的已弃用参数。

7.2. 弃用

7.3. 显著变更

8. Active Record

有关详细更改,请参阅变更日志

8.1. 移除

  • 移除已弃用的 Rails.application.config.active_record.suppress_multiple_database_warning

  • 移除已弃用对使用不存在的属性名称调用 alias_attribute 的支持。

  • 移除 ActiveRecord::Base.remove_connection 中已弃用的 name 参数。

  • 移除已弃用的 ActiveRecord::Base.clear_active_connections!

  • 移除已弃用的 ActiveRecord::Base.clear_reloadable_connections!

  • 移除已弃用的 ActiveRecord::Base.clear_all_connections!

  • 移除已弃用的 ActiveRecord::Base.flush_idle_connections!

  • 移除已弃用的 ActiveRecord::ActiveJobRequiredError

  • 移除已弃用对在连接适配器中使用 2 个参数定义 explain 的支持。

  • 移除已弃用的 ActiveRecord::LogSubscriber.runtime 方法。

  • 移除已弃用的 ActiveRecord::LogSubscriber.runtime= 方法。

  • 移除已弃用的 ActiveRecord::LogSubscriber.reset_runtime 方法。

  • 移除已弃用的 ActiveRecord::Migration.check_pending 方法。

  • 移除已弃用对将 SchemaMigrationInternalMetadata 类作为参数传递给 ActiveRecord::MigrationContext 的支持。

  • 移除已弃用通过复数名称引用单数关联的行为。

  • 移除已弃用的 TestFixtures.fixture_path

  • 移除已弃用对 ActiveRecord::Base#read_attribute(:id) 返回自定义主键值的支持。

  • 移除已弃用对将编码器和类作为第二个参数传递给 serialize 的支持。

  • 移除数据库适配器中已弃用的 #all_foreign_keys_valid?

  • 移除已弃用的 ActiveRecord::ConnectionAdapters::SchemaCache.load_from

  • 移除已弃用的 ActiveRecord::ConnectionAdapters::SchemaCache#data_sources

  • 移除已弃用的 #all_connection_pools

  • 移除已弃用对在未提供 role 参数时将 #connection_pool_list#active_connections?#clear_active_connections!#clear_reloadable_connections!#clear_all_connections!#flush_idle_connections! 应用于当前角色连接池的支持。

  • 移除已弃用的 ActiveRecord::ConnectionAdapters::ConnectionPool#connection_klass

  • 移除已弃用的 #quote_bound_value

  • 移除已弃用对引用 ActiveSupport::Duration 的支持。

  • 移除已弃用对将 deferrable: true 传递给 add_foreign_key 的支持。

  • 移除已弃用对将 rewhere 传递给 ActiveRecord::Relation#merge 的支持。

  • 移除已弃用通过 returnbreakthrow 退出事务块时回滚事务的行为。

8.2. 弃用

  • 弃用 Rails.application.config.active_record.allow_deprecated_singular_associations_name

  • 弃用 Rails.application.config.active_record.commit_transaction_on_non_local_return

8.3. 显著变更

  • ActiveRecord::Base.establish_connection 不再将 ActiveRecord::Base.connection.active? 设置为 true。如果需要此行为,可以使用 ActiveRecord::Base.connection.verify! 代替。

9. Active Storage

有关详细更改,请参阅变更日志

9.1. 移除

  • 移除已弃用的 config.active_storage.replace_on_assign_to_many

  • 移除已弃用的 config.active_storage.silence_invalid_content_types_warning

9.2. 弃用

9.3. 显著变更

10. Active Model

有关详细更改,请参阅变更日志

10.1. 移除

10.2. 弃用

10.3. 显著变更

11. Active Support

有关详细更改,请参阅变更日志

11.1. 移除

  • 移除已弃用的 ActiveSupport::Notifications::Event#childrenActiveSupport::Notifications::Event#parent_of?

  • 移除已弃用对不传递弃用器调用以下方法的支持

    • 弃用
    • 弃用常量
    • ActiveSupport::Deprecation::DeprecatedObjectProxy.new
    • ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new
    • ActiveSupport::Deprecation::DeprecatedConstantProxy.new
    • assert_deprecated
    • assert_not_deprecated
    • collect_deprecations
  • 移除已弃用的 ActiveSupport::Deprecation 委托给实例。

  • 移除已弃用的 SafeBuffer#clone_empty

  • ArrayDateDateTimeTime 中移除已弃用的 #to_default_s

  • 移除缓存存储中已弃用的 :pool_size:pool_timeout 选项。

  • 移除已弃用对 config.active_support.cache_format_version = 6.1 的支持。

  • 移除已弃用常量 ActiveSupport::LogSubscriber::CLEARActiveSupport::LogSubscriber::BOLD

  • 移除已弃用对使用位置布尔值在 ActiveSupport::LogSubscriber#color 中加粗日志文本的支持。

  • 移除已弃用的 config.active_support.disable_to_s_conversion

  • 移除已弃用的 config.active_support.remove_deprecated_time_with_zone_name

  • 移除已弃用的 config.active_support.use_rfc4122_namespaced_uuids

  • 移除已弃用对将 Dalli::Client 实例传递给 MemCacheStore 的支持。

11.2. 弃用

11.3. 显著变更

12. Active Job

有关详细更改,请参阅变更日志

12.1. 移除

  • 移除已弃用的 BigDecimal 参数原始序列化器。

  • 移除已弃用对将数字值设置为 scheduled_at 属性的支持。

  • 移除 retry_on:wait 的已弃用 :exponentially_longer 值。

12.2. 弃用

  • 弃用 Rails.application.config.active_job.use_big_decimal_serializer

12.3. 显著变更

13. Action Text

有关详细更改,请参阅变更日志

13.1. 移除

13.2. 弃用

13.3. 显著变更

14. Action Mailbox

有关详细更改,请参阅变更日志

14.1. 移除

14.2. 弃用

14.3. 显著变更

15. Ruby on Rails 指南

有关详细更改,请参阅变更日志

15.1. 显著变更

16. 致谢

请参阅Rails 贡献者完整列表,感谢许多人花费大量时间使 Rails 成为一个稳定而健壮的框架。向他们所有人致敬。



回到顶部