1. 升级到 Rails 8.1
如果您正在升级现有应用程序,最好在开始之前进行良好的测试覆盖。您还应该首先升级到 Rails 8.0(如果您尚未升级),并确保您的应用程序在尝试升级到 Rails 8.1 之前仍能按预期运行。在升级 Ruby on Rails 指南中提供了升级时需要注意的事项列表。
2. 主要特性
2.1. Active Job 延续
长时间运行的作业现在可以分解为离散的步骤,允许在重启后从上次完成的步骤而不是从头开始执行。这在使用 Kamal 进行部署时特别有用,因为 Kamal 默认只给运行作业的容器三十秒时间关闭。
示例
class ProcessImportJob < ApplicationJob
include ActiveJob::Continuable
def perform(import_id)
@import = Import.find(import_id)
# block format
step :initialize do
@import.initialize
end
# step with cursor, the cursor is saved when the job is interrupted
step :process do |step|
@import.records.find_each(start: step.cursor) do |record|
record.process
step.advance! from: record.id
end
end
# method format
step :finalize
end
private
def finalize
@import.finalize
end
end
3. 结构化事件报告
Rails 中的默认日志记录器非常适合人类阅读,但不太适合后处理。新的事件报告器为在 Rails 应用程序中生成结构化事件提供了一个统一的接口。
Rails.event.notify("user.signup", user_id: 123, email: "user@example.com")
它支持向事件添加标签。
Rails.event.tagged("graphql") do
# Event includes tags: { graphql: true }
Rails.event.notify("user.signup", user_id: 123, email: "user@example.com")
end
以及上下文: ```ruby
所有事件都将包含上下文:{request_id: "abc123", shop_id: 456}
Rails.event.set_context(request_id: "abc123", shop_id: 456) ```
事件会发送给订阅者。应用程序注册订阅者以控制事件的序列化和发送方式。订阅者必须实现一个 #emit 方法,该方法接收事件哈希。
class LogSubscriber
def emit(event)
payload = event[:payload].map { |key, value| "#{key}=#{value}" }.join(" ")
source_location = event[:source_location]
log = "[#{event[:name]}] #{payload} at #{source_location[:filepath]}:#{source_location[:lineno]}"
Rails.logger.info(log)
end
end
4. 本地 CI
开发人员机器变得非常快,拥有大量核心,这使得它们非常适合本地运行即使是相对较大的测试套件。
这使得对于许多中小型应用程序来说,摆脱云设置来进行所有 CI 不仅可行而且值得期望,因此 Rails 添加了一个默认的 CI 声明 DSL,它在 config/ci.rb 中定义并通过 bin/ci 运行。它看起来像这样:
CI.run do
step "Setup", "bin/setup --skip-server"
step "Style: Ruby", "bin/rubocop"
step "Security: Gem audit", "bin/bundler-audit"
step "Security: Importmap vulnerability audit", "bin/importmap audit"
step "Security: Brakeman code analysis", "bin/brakeman --quiet --no-pager --exit-on-warn --exit-on-error"
step "Tests: Rails", "bin/rails test"
step "Tests: Seeds", "env RAILS_ENV=test bin/rails db:seed:replant"
# Requires the `gh` CLI and `gh extension install basecamp/gh-signoff`.
if success?
step "Signoff: All systems go. Ready for merge and deploy.", "gh signoff"
else
failure "Signoff: CI failed. Do not merge or deploy.", "Fix the issues and try again."
end
end
与 gh 的可选集成确保 PR 必须通过 CI 运行才能合并。
5. Markdown 渲染
Markdown 已成为 AI 的通用语言,Rails 通过使其更容易响应 Markdown 请求并直接渲染它们来支持这一采用。
class Page
def to_markdown
body
end
end
class PagesController < ActionController::Base
def show
@page = Page.find(params[:id])
respond_to do |format|
format.html
format.md { render markdown: @page }
end
end
end
6. 命令行凭证获取
Kamal 现在可以轻松地从加密的 Rails 凭证存储中获取其部署密钥。这使其成为外部密钥存储的低保真替代方案,只需要主密钥即可工作。
# .kamal/secrets
KAMAL_REGISTRY_PASSWORD=$(rails credentials:fetch kamal.registry_password)
7. 已弃用的关联
Active Record 关联现在可以标记为已弃用。
class Author < ApplicationRecord
has_many :posts, deprecated: true
end
这样,posts 关联的使用情况将被报告。这包括显式 API 调用,例如:
author.posts
author.posts = ...
以及其他,以及间接使用,例如:
author.preload(:posts)
通过嵌套属性使用等等。
支持三种报告模式(:warn、:raise 和 :notify),并且可以启用或禁用回溯,尽管无论如何您始终会获得报告使用位置。默认是 :warn 模式和禁用回溯。
8. Railties
有关详细更改,请参阅更新日志。
8.1. 移除
删除已弃用的
rails/console/methods.rb文件。删除已弃用的
bin/rake stats命令。删除已弃用的
STATS_DIRECTORIES。
8.2. 弃用
8.3. 显著变更
9. Action Cable
有关详细更改,请参阅更新日志。
9.1. 移除
9.2. 弃用
9.3. 显著变更
10. Action Pack
有关详细更改,请参阅更新日志。
10.1. 移除
删除对参数解析器中跳过参数名称中前导方括号的已弃用支持。
之前
ActionDispatch::ParamBuilder.from_query_string("[foo]=bar") # => { "foo" => "bar" } ActionDispatch::ParamBuilder.from_query_string("[foo][bar]=baz") # => { "foo" => { "bar" => "baz" } }之后
ActionDispatch::ParamBuilder.from_query_string("[foo]=bar") # => { "[foo]" => "bar" } ActionDispatch::ParamBuilder.from_query_string("[foo][bar]=baz") # => { "[foo]" => { "bar" => "baz" } }删除对使用分号作为查询字符串分隔符的已弃用支持。
之前
ActionDispatch::QueryParser.each_pair("foo=bar;baz=quux").to_a # => [["foo", "bar"], ["baz", "quux"]]之后
ActionDispatch::QueryParser.each_pair("foo=bar;baz=quux").to_a # => [["foo", "bar;baz=quux"]]删除对将路由路由到多个路径的已弃用支持。
10.2. 弃用
- 弃用
Rails.application.config.action_dispatch.ignore_leading_brackets。
10.3. 显著变更
- 新 Rails 应用程序在开发环境中重定向现在是详细的。要在现有应用程序中启用它,请将
config.action_dispatch.verbose_redirect_logs = true添加到您的config/development.rb文件中。
11. Action View
有关详细更改,请参阅更新日志。
11.1. 移除
11.2. 弃用
11.3. 显著变更
12. Action Mailer
有关详细更改,请参阅更新日志。
12.1. 移除
12.2. 弃用
12.3. 显著变更
13. Active Record
有关详细更改,请参阅更新日志。
13.1. 移除
删除 SQLite3 适配器已弃用的
:retries选项。删除 MySQL 已弃用的
:unsigned_float和:unsigned_decimal列方法。
13.2. 弃用
弃用在没有
order的情况下使用依赖于顺序的查找方法(例如#first)。弃用
ActiveRecord::Base.signed_id_verifier_secret,转而使用Rails.application.message_verifiers(如果密钥特定于模型,则使用Model.signed_id_verifier)。弃用在关联中使用未持久化记录的
insert_all/upsert_all。弃用将
WITH、WITH RECURSIVE和DISTINCT与update_all一起使用。
13.3. 显著变更
schema.rb中的表列现在按字母顺序排序。
14. Active Storage
有关详细更改,请参阅更新日志。
14.1. 移除
- 删除已弃用的
:azure存储服务。
14.2. 弃用
14.3. 显著变更
15. Active Model
有关详细更改,请参阅更新日志。
15.1. 移除
15.2. 弃用
15.3. 值得注意的更改
16. Active Support
有关详细更改,请参阅更新日志。
16.1. 移除
移除已弃用的向
Time#since传递 Time 对象。移除已弃用的
Benchmark.ms方法。它现在在benchmarkgem 中定义。移除已弃用的带有
ActiveSupport::TimeWithZone的Time实例的添加。移除已弃用的
to_time保留系统本地时间的支持。它现在将始终保留接收者时区。
16.2. 弃用
弃用
config.active_support.to_time_preserves_timezone。弃用
String#mb_chars和ActiveSupport::Multibyte::Chars。弃用
ActiveSupport::Configurable。
16.3. 值得注意的更改
17. Active Job
有关详细更改,请参阅更新日志。
17.1. 移除
移除设置
ActiveJob::Base.enqueue_after_transaction_commit为:never、:always和:default的支持。移除已弃用的
Rails.application.config.active_job.enqueue_after_transaction_commit。移除已弃用的内部
SuckerPunch适配器,转而使用sucker_punchgem 中包含的适配器。
17.2. 弃用
自定义 Active Job 序列化程序必须具有公共的
#klass方法。弃用内置的
sidekiq适配器(现在由sidekiqgem 提供)。
17.3. 值得注意的更改
18. Action Text
有关详细更改,请参阅更新日志。
18.1. 移除
18.2. 弃用
18.3. 值得注意的更改
19. Action Mailbox
有关详细更改,请参阅更新日志。
19.1. 移除
19.2. 弃用
19.3. 值得注意的更改
20. Ruby on Rails 指南
有关详细更改,请参阅更新日志。
20.1. 值得注意的更改
21. 鸣谢
请参阅Rails 贡献者完整列表,感谢许多人花费大量时间使 Rails 成为一个稳定而健壮的框架。向他们所有人致敬。