2025 年 8 月 15 日,星期五

Rails 中新增结构化事件报告功能!

发布者:Emmanuel Hayford

大家好!这里是 Emmanuel Hayford,为您带来 Rails 代码库的最新更新!

添加 #assert_events_reported 测试辅助方法
Rails 添加了一个新的测试辅助方法,允许您断言在某个代码块中**触发了多个**事件——**不区分顺序**,支持**载荷 (payload)** 和 **标签 (tag)** 匹配,并且会**忽略额外的事件**。这对于一次性发出多个仪器化事件的工作流程非常方便。

assert_events_reported([
  { name: "user.created", payload: { id: 123 } },
  { name: "email.sent",   payload: { to: "user@example.com" } }
]) do
  create_user_and_send_welcome_email
end

为一次性排队多个电子邮件添加 deliver_all_later
现在您可以一次性排队发送多封电子邮件,从而减少与队列后端的往返次数。构建一个 MessageDelivery 对象数组并一次性推送它们。选项(如 queue:)将被转发给作业。底层使用了 ActiveJob.perform_all_later,如果适配器不支持批量排队,它将优雅地回退到单独排队。 

# Build deliveries
user_emails = User.find_each.map { |user| Notifier.welcome(user) }

# Enqueue all at once
ActionMailer.deliver_all_later(user_emails)

为错误页面添加“复制为文本”按钮
错误页面上的“复制为文本”按钮 — 开发环境的错误页面现在包含一个标题中的“复制为文本”按钮,可以将异常的简洁纯文本版本复制到剪贴板。

copy.png

从 button_to 中的隐藏输入中移除 autocomplete=”off”
form_tagtoken_tagmethod_tag 生成的隐藏输入以及 button_to 内部的隐藏参数不再强制设置 autocomplete=”off”。一个新的设置 config.action_view.remove_hidden_field_autocomplete 控制此行为(对于现有应用程序,默认值仍为 false;load_defaults 8.1 将其设置为 true)。

Rails.application.config.action_view.remove_hidden_field_autocomplete = true

Rails 中的结构化事件报告
Rails 添加了一流的事件报告器 (Event Reporter),具有统一的结构化遥测 API。可以通过 Rails.event 访问,并使用上下文和标签来发出事件。

Rails.event.set_context(request_id: "abc123", shop_id: 456)

Rails.event.tagged("graphql") do
  Rails.event.notify("user.signup", user_id: 123, email: "user@example.com")
end

应用程序订阅事件并选择编码器(例如 JSON)进行输出。

class MySubscriber
  def emit(event)
    encoded = ActiveSupport::EventReporter.encoder(:json).encode(event)
    StructuredLogExporter.export(encoded)
  end
end

Rails.event.subscribe(MySubscriber.new)

Action Cable:stream_for 现在支持复合通道
现在您可以向复合目标 (composite targets) 进行流式传输和广播,方法是将一个数组传递给 ActionCable::Channel#stream_for / # broadcast_to,这与 Turbo 的复合广播类似。这允许您一次性将流作用于多个模型。

class ChatChannel < ApplicationCable::Channel
  def subscribed
    stream_for [room, current_user]  # composite target
  end
end

使用 scope 在控制器之间共享速率限制
现在,您可以通过将 scope: 传递给 rate_limit 来在多个控制器之间共享单个速率限制计数器。默认情况下,限制是按控制器作用域的,但使用相同的 scope 值可以让不同的控制器共享同一个桶。

您可以在 此处查看完整的更改列表。
上周,我们有 35 位贡献者为 Rails 代码库做出了贡献!

下次再见!

订阅即可通过电子邮件获取这些更新。

每周为您提供来自 Rails 的有趣提交、拉取请求等方面的内部快讯。

订阅以通过邮件获取这些更新。