# 修复：由于近期 ruby-i18n 更新导致的 I18n 回归问题

**URL:** https://meta.discourse.org/t/fix-i18n-regression-due-to-recent-ruby-i18n-update/411859
**Category:** Bug
**Created:** [2026年九月8日 05:21 UTC](https://meta.discourse.org/t/fix-i18n-regression-due-to-recent-ruby-i18n-update/411859 "2026-09-08T05:21:58Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![small-lovely-cat](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/small-lovely-cat/32/553546_2.png) [@small-lovely-cat](https://meta.discourse.org/u/small-lovely-cat)
#### Post date: [2026年九月8日 05:21 UTC](https://meta.discourse.org/t/fix-i18n-regression-due-to-recent-ruby-i18n-update/411859/1 "2026-09-08T05:21:58Z")

</div>

在 [DEPS: Bump i18n from 1.14.8 to 1.15.2 - Pull Request #41242 - discourse/discourse - GitHub](https://github.com/discourse/discourse/pull/41242) 中，我们将 ruby-i18n 更新到了 1.15.x，但该版本存在一个缺陷。

> **分析**
>
> 首先，配置现在存储在 Fiber 上：
> 
> ```plaintext
> Fiber[:i18n_config]
> 
> ```
> 
> 新实现会检测当前 Fiber 是否继承了一个由其他 Fiber 拥有的配置：
> 
> ```plaintext
> if current.respond_to?(:owned_by?) && !current.owned_by?(Fiber.current)
> current = current.dup
> Fiber[:i18n_config] = current
> end
> 
> ```
> 
> 问题出在 `I18n::Config#initialize_copy` 方法中：
> 
> ```plaintext
> def initialize_copy(other)
> @owner = Fiber.current
> end
> 
> ```
> 
> 它更改了复制后的配置的拥有者，但没有清除复制的 `@locale`，即子 Fiber 会继承父 Fiber 中显式设置的 `@locale`。
> 
> 因此，如果父 Fiber 当前拥有：
> 
> ```plaintext
> I18n.locale == :zh_CN
> 
> ```
> 
> 子 Fiber 可能会继承一个仍然包含以下内容的复制配置：
> 
> ```plaintext
> @locale == :zh_CN
> 
> ```
> 
> 尽管该子 Fiber 现在代表一个不同的请求，该请求本应解析为英语。

这导致 Discourse 出现问题。当用户使用的显示语言与默认语言不同时，例如站点默认语言为中文，而显示语言为英语时，页面可能会意外地显示为中文，或者出现英语和中文混合的情况。

已提交一个 commit 回滚该版本更新，并添加了一些 spec。在等待上游修复之前，暂停更新可能是一个好主意。

> <https://github.com/discourse/discourse/pull/43363>
>
> In #41242, we
> updated the ruby-i18n to 1.15.x, however, this upstream version h…as a defection.
> 
> \---
> 
> The configuration is now stored on the Fiber:
> 
> \`\`\`ruby
> Fiber\[:i18n\_config\]
> \`\`\`
> 
> The new implementation detects when a Fiber inherited a configuration owned by another Fiber:
> 
> \`\`\`ruby
> if current.respond\_to?(:owned\_by?) && !current.owned\_by?(Fiber.current)
> current = current.dup
> Fiber\[:i18n\_config\] = current
> end
> \`\`\`
> 
> The problem is in \`I18n::Config#initialize\_copy\`:
> 
> \`\`\`ruby
> def initialize\_copy(other)
> @owner = Fiber.current
> end
> \`\`\`
> 
> It changes the owner of the copied configuration, but it does not clear the copied \`@locale\`, i.e., Child Fiber inherits parent's explicit \`@locale\`.
> 
> So if the parent Fiber currently has:
> 
> \`\`\`ruby
> I18n.locale == :zh\_CN
> \`\`\`
> 
> a child Fiber can inherit a copied configuration that still contains:
> 
> \`\`\`ruby
> @locale == :zh\_CN
> \`\`\`
> 
> even though that child Fiber now represents a different request that should resolve to English.
> 
> \---
> 
> This cause a problem in discourse. When the user is using a display language different from the default language. Say, Chinese as the site default language and English as the display language, pages may accidentally display in Chinese, or a combination of English and Chinese.
> 
> This commit rollback the version update and added some spec, maybe pausing the update until upstream fix that will be a great idea.
> 
> Related issue: https://github.com/ruby-i18n/i18n/issues/742

---

<div class="post-metadata">

### Author: ![nat](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nat/32/235063_2.png) [@nat](https://meta.discourse.org/u/nat)
#### Post date: [2026年九月8日 06:14 UTC](https://meta.discourse.org/t/fix-i18n-regression-due-to-recent-ruby-i18n-update/411859/2 "2026-09-08T06:14:21Z")

</div>

感谢反馈，我正在查看。

---

<div class="post-metadata">

### Author: ![nat](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nat/32/235063_2.png) [@nat](https://meta.discourse.org/u/nat)
#### Post date: [2026年九月12日 00:00 UTC](https://meta.discourse.org/t/fix-i18n-regression-due-to-recent-ruby-i18n-update/411859/4 "2026-09-12T00:00:35Z")

</div>

该主题在3天后自动关闭。不再允许新的回复。
