Rails 7.0 发布说明深度解读:升级路径与各框架关键行为变更全解析
本篇基于 Rails 官方的 7.0 发布说明(guides/source/7_0_release_notes.md)展开,系统梳理升级到 Rails 7.0 的前置条件、Sprockets 依赖解耦、Active Record 事务与查询合并的行为变更、button_to 的 HTTP 动词推断等核心特性,并结合仓库源码印证各变更的实际落地方式,帮助你在从 6.1 升级到 7.0(乃至更晚版本)时准确预判破坏性改动。需要说明的是,当前仓库主干版本为 8.2.0.alpha(见 RAILS_VERSION),本文内容适用于理解 7.0 这一里程碑的变更脉络及其在后续版本中的演进。
升级前置条件:Ruby 版本要求与升级路径
Rails 7.0 对运行环境提出了明确的版本底线:
- 必须 Ruby 2.7.0+;
- 推荐 Ruby 3.0+。
官方对存量应用升级给出了两步走建议:
- 先确保应用有良好的测试覆盖率——没有回归网兜底的情况下直接跨大版本升级风险很高;
- 先升级到 Rails 6.1,确认应用行为符合预期后,再升级到 7.0。
升级时需要逐项对照的破坏性改动清单,收录在 Upgrading Ruby on Rails 指南的 “From Rails 6.1 to Rails 7.0” 章节中,与本文各节的框架级变更互为补充。
Railties:Sprockets 成为可选依赖
这是 Rails 7.0 中最具实操影响的一项变更:rails gem 不再依赖 sprockets-rails。Sprockets 从框架的默认配置中解耦出来,成为可选依赖。
如果你的应用仍在使用 Sprockets 管理静态资源,必须在 Gemfile 中显式声明:
gem "sprockets-rails"
这一变更的背景是 Rails 官方正在向 Propshaft 等更轻量的资产方案迁移,将资产管道从核心依赖中剥离可以让不需要 Sprockets 的应用少装一层依赖。升级检查时,凡是没有显式声明该 gem 且仍依赖 app/assets 目录下 Sprockets 逻辑的应用,都会在新版本中报缺失依赖错误。
另外,Railties 在 7.0 中还移除了 dbconsole 中已弃用的 config 用法(见 railties/CHANGELOG.md 的对应条目)。
Action Pack:集中清理 6.x 时代的弃用 API
Action Pack 在 7.0 中的变更以“移除弃用项”为主,共 4 项,主要涉及路由与测试工具:
- 移除弃用的
ActionDispatch::Response.return_only_media_type_on_content_type; - 移除弃用的
Rails.config.action_dispatch.hosts_response_app(该配置在 7.0 之前已被默认开启的config.hosts机制取代); - 移除弃用的
ActionDispatch::SystemTestCase#host!; - 移除
fixture_file_upload中允许传入相对fixture_path路径的弃用支持。
前两项的移除意味着:如果你的应用还在旧版配置中设置 hosts_response_app,或依赖 return_only_media_type_on_content_type 的旧行为,升级后将直接报错而非警告。系统测试中 host! 的移除则要求改为通过 driven_by 或浏览器实例管理 host。
Action View:button_to 自动推断 HTTP 动词
这是 7.0 中对前端行为可见性影响最大的一项变更:当 button_to 使用 Active Record 对象构建 URL 时,HTTP 动词会自动从路由推断。此前 button_to 一律默认 post,升级后按钮实际发出的请求方法可能改变:
button_to("Do a POST", [:do_post_action, Workshop.find(1)])
# 升级前
#=> <input type="hidden" name="_method" value="post" autocomplete="off" />
# 升级后(路由声明的动词是 patch 时)
#=> <input type="hidden" name="_method" value="patch" autocomplete="off" />
这个行为在当前源码中可以清晰看到:navigation_helper.rb 中 button_to 的核心逻辑是——
method = (html_options.delete("method").presence || method_for_options(options)).to_s
即:优先采用显式传入的 method 选项,否则回退到 method_for_options(options) 依据路由信息推断。因此推断只在“未显式指定 method 且 URL 由路由+对象构建”时发生。升级时的自查方法:搜索所有未传 method: 选项、且 action 路由并非 post 的 button_to 调用,确认控制器端的 wrap_parameters 与 CSRF 校验逻辑与新动词兼容。
Action Mailer:统一为 MailDeliveryJob
7.0 移除了已弃用的 ActionMailer::DeliveryJob 与 ActionMailer::Parameterized::DeliveryJob,统一收敛为 ActionMailer::MailDeliveryJob。在当前仓库中,该类定义于 mail_delivery_job.rb,其 perform 签名同时承载了参数化投递与普通投递两种路径:
class MailDeliveryJob < ActiveJob::Base
def perform(mailer, mail_method, delivery_method, args:, kwargs: nil, params: nil)
params: 参数正是从 Parameterized::DeliveryJob 合并而来的痕迹。升级时需要注意:
- 队列名称从
ActionMailer::DeliveryJob/ActionMailer::Parameterized::DeliveryJob变为ActionMailer::MonitorJob之外的单一ActionMailer::MailDeliveryJob,旧队列名残留的任务不会自动被消费,升级窗口内需要手动处理已入队的旧任务; - 任何硬编码旧 Job 类名的监控、重试逻辑都要同步更新。
Active Record:事务回滚、条件合并与 PostgreSQL interval 变更
Active Record 是 7.0 变更最密集的框架,按重要程度分述如下。
1. 事务块提前返回时回滚而非提交
7.0 之前,事务块中提前 return(以及更隐蔽的超时中断)会走 commit 路径,导致不完整的事务被提交。7.0 起,块提前返回时事务改为回滚。这一变更的动机在原文档中有明确说明:超时机制曾在事务块内部触发中断,旧行为会把残缺事务提交进数据库。从源码结构看,该逻辑落在 transaction 实现的收尾分支中(参见 activerecord/CHANGELOG.md 中 “Rollback transactions when the block returns earlier than expected” 条目)。对业务的影响:所有依赖“提前 return 也算提交”的隐式约定的代码(比如用 return 代替 raise 的事务保护)需要在升级前显式改为 return 前手动回滚或抛出异常。
2. 同列条件合并:rewhere 语义转正
merge 时同列条件冲突的处理在 6.1 是过渡状态(IN 子句被替换、范围条件双方共存),7.0 统一为:后者(被合并侧)条件一致性地替换前者,rewhere: true 选项成为唯一迁移手段:
# Rails 6.1:IN 子句被替换
Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
# Rails 6.1:范围条件双方共存(已弃用行为)
Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => []
# 用 rewhere 提前对齐 7.0 行为
Author.where(id: david.id..mary.id).merge(Author.where(id: bob), rewhere: true) # => [bob]
# Rails 7.0:两种写法行为一致,均被替换
Author.where(id: [david.id, mary.id]).merge(Author.where(id: bob)) # => [bob]
Author.where(id: david.id..mary.id).merge(Author.where(id: bob)) # => [bob]
实操建议:在 6.1 阶段全局搜索 .merge( 并对涉及条件覆盖的调用补上 rewhere: true,跑一遍测试即可确认对齐 7.0 语义。
3. PostgreSQL interval 列返回 ActiveSupport::Duration
7.0 移除了 :interval 列返回字符串的弃用警告,interval 列从此直接返回 ActiveSupport::Duration 对象。若业务必须保留旧的字符串行为,可以在模型中显式声明列类型:
attribute :column, :string
4. 大规模移除弃用 API(升级自查清单)
7.0 一次性移除了自 Rails 4.x~6.x 积累的弃用面,主要包括:
- 连接与配置:
connected_to的database关键字参数、"primary"连接规格名、DatabaseConfig#config、ActiveRecord::Base.connection_config、configurations.default_hash/configurations.to_h、DatabaseConfig#spec_name; - SQL 安全:
ActiveRecord::Base.allow_unsafe_raw_sql(7.0 起不安全 SQL 直接抛错,不再提供开关)、ActiveRecord::Base.arel_attribute、type_cast传入列名的支持、对ActiveRecord::Base对象执行 quote/type-cast 的支持; - 序列化:移除以 Rails 4.1/4.2 YAML 格式加载
ActiveRecord::Base实例的支持; - 查询:
Model.reorder(nil).first借助非确定性排序检索的弃用支持; - 任务 API:
Tasks::DatabaseTasks下的schema_file、dump_filename、current_config、spec、带environment/name参数的schema_up_to_date?等,以及一批db:structure:*、db:test:load_structure*、db:schema:load_if_ruby等弃用 rake 任务; - 连接与结果对象:
ActiveRecord::Connection#allowed_index_name_length、#in_clause_length、ActiveRecord::Result#map!/#collect!、ActiveRecord::Base#remove_connection。
其中 Tasks::DatabaseTasks.schema_file_type 则在 7.0 中被新弃用(后续版本移除)。这类清理的共性是:7.0 是 Rails 6 系列弃用债务的“总清账”,升级前建议用 Rails::Deprecation 日志扫一遍 6.1 下的全量弃用告警。
Active Model:Errors 彻底告别 Hash 接口
7.0 移除了把 ActiveModel::Errors 当 Hash 使用的全部旧接口:to_h、slice!、values、keys、to_xml,以及通过 #messages 拼接(concat)、clear、delete、[]= 修改错误的隐式支持。同时移除了对 Rails 5.x 错误格式的 Marshal/YAML 反序列化支持,以及 5.x 格式 ActiveModel::AttributeSet 的 Marshal 支持。
影响面提示:所有形如 errors.to_h 序列化进 JSON/缓存、或从旧版本遗留的序列化错误数据反序列化的代码路径都会失效,需要迁移到 errors.details / errors.attribute_names 等现代接口。
Active Support:to_s 传 format 弃用,让位给 to_fs
这是 7.0 中影响面最广的弃用项:对 Array、Range、Date、DateTime、Time、BigDecimal、Float、Integer 调用带 format 参数的 #to_s 被弃用,应改用 #to_fs。
弃用的动机是承接 Ruby 3.1 对字符串插值的底层优化——不再覆盖这些类的 to_s 后,"#{obj}" 走 Ruby 原生的更快路径。对应开关:
- 新应用:默认不覆盖上述类的
to_s; - 存量应用:通过
config.active_support.disable_to_s_conversion显式关闭覆盖以获取性能收益(注意:该配置在 Rails 7.1 被弃用、7.2 移除,属于过渡性开关)。
另外 7.0 还移除了 4 项弃用:config.active_support.use_sha1_digests、URI.parser、Range#include? 用于日期时间范围成员判断的旧行为、ActiveSupport::Multibyte::Unicode.default_normalization_form。
Active Job:回调中断语义定型
7.0 定型了回调链的中断语义:当 after_enqueue / after_perform 回调链中前一个回调通过 throw :abort 中断时,后续回调不再执行——旧版本“中断后仍继续执行”的行为被移除。同时移除了 :return_false_on_aborted_enqueue 配置选项。
值得注意的过渡点:Rails.config.active_job.skip_after_callbacks_if_terminated 在 7.0 中被弃用(后续版本移除)。当前仓库的 callbacks.rb 中 define_callbacks 仍保留 skip_after_callbacks_if_terminated 关键字参数,说明该参数已从“用户可配置的开关”退化为回调注册层的内部机制——这也是它在配置层面被弃用的原因。
Action Mailbox:移除 Mailgun 旧凭据通道
7.0 移除了两项 Mailgun 接入的弃用通道:
Rails.application.credentials.action_mailbox.mailgun_api_key;- 环境变量
MAILGUN_INGRESS_API_KEY。
Mailgun ingress 的凭据管理统一收敛到 ingress 专用的 credentials 体系(见 actionmailbox 的 config/initializers 相关文档与 CHANGELOG)。升级时若应用依赖上述旧配置项,需在部署前迁移凭据来源,否则 Mailgun 回调验签将直接失败。
各框架 Changelog 对照索引
发布说明中每个框架都指向其详细 Changelog,在当前仓库中对应的文件如下,升级与回归验证时可逐项核对:
| 框架 | Changelog 路径 |
|---|---|
| Railties | railties/CHANGELOG.md |
| Action Pack | actionpack/CHANGELOG.md |
| Action View | actionview/CHANGELOG.md |
| Action Mailer | actionmailer/CHANGELOG.md |
| Action Cable | actioncable/CHANGELOG.md |
| Active Record | activerecord/CHANGELOG.md |
| Active Storage | activestorage/CHANGELOG.md |
| Active Model | activemodel/CHANGELOG.md |
| Active Support | activesupport/CHANGELOG.md |
| Active Job | activejob/CHANGELOG.md |
| Action Text | actiontext/CHANGELOG.md |
| Action Mailbox | actionmailbox/CHANGELOG.md |
| Guides | guides/CHANGELOG.md |
升级 7.0 的落地检查清单
综合以上变更,一份可执行的升级清单如下:
- 环境:Ruby 升至 2.7+(推荐 3.0+);
- 资产管道:仍在用 Sprockets 的应用在 Gemfile 中显式添加
gem "sprockets-rails"; - 先升 6.1 并开启弃用日志,收集全量 deprecation 告警,对照本文各框架 Removals 清单逐项清零;
- Active Record:审查事务块中的提前
return路径;为条件覆盖场景补rewhere: true;PostgreSQLinterval列确认Duration类型影响; - Active Job:确认
MailDeliveryJob队列迁移方案,清理旧队列名; - Active Support:批量替换带 format 的
to_s为to_fs,评估disable_to_s_conversion开关(仅 7.0 生效); - 视图层:排查
button_to动词推断带来的请求方法变化; - Action Mailbox:迁移 Mailgun 凭据配置。
Rails 7.0 的整体定位是一次“清账式”版本:新增特性克制,重点是清除 4.x 以来积累的弃用债务并固化 6.1 的过渡行为。理解上述每一项变更的“旧行为 → 新行为”映射,配合各框架 Changelog 的条目级核对,即可把跨大版本升级的风险控制在可回滚范围内。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00