You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails中ActionView在delayed_job调用时因I18n.fallbacks崩溃的修复方法

Rails 4 + Delayed Job 邮件发送 TypeError 问题修复

问题场景

我在Rails 4应用里用Delayed Job发送邮件,控制台执行了:

ActionMailer::Base.mail(from: 'mail@example.com', to: 'foo@example.com', subject: 'test', body: "Hello, you've got mail!").deliver_later

本地触发任务时用:

Delayed::Job.last.invoke_job

结果任务崩溃,报错:

Devise::Mailer#invitation_instructions: processed outbound mail in 56234.1ms
Performed ActionMailer::DeliveryJob from DelayedJob(mailers) in 56880.04ms
TypeError: no implicit conversion of nil into Array
from /Users/de/.rvm/gems/ruby-2.4.0/gems/actionview-4.2.10/lib/action_view/lookup_context.rb:51:in `concat'
from /Users/de/.rvm/gems/ruby-2.4.0/gems/actionview-4.2.10/lib/action_view/lookup_context.rb:51:in `block in <class:LookupContext>'
from /Users/de/.rvm/gems/ruby-2.4.0/gems/actionview-4.2.10/lib/action_view/lookup_context.rb:39:in `initialize_details'
from /Users/de/.rvm/gems/ruby-2.4.0/gems/actionview-4.2.10/lib/action_view/lookup_context.rb:205:in `initialize'
...

排查后发现问题出在ActionView的lookup_context.rb第51行:

register_detail(:locale) do
  locales = [I18n.locale]
  locales.concat(I18n.fallbacks[I18n.locale]) if I18n.respond_to? :fallbacks # 此处崩溃
end

调试信息显示:

  • I18n.locale => :de
  • I18n.fallbacks => {:en=>[]}

因为I18n.fallbacks[:de]返回nil,调用concat时试图把nil转成数组,就抛出了TypeError。

问题原因

你的I18n fallback配置里没有包含:de这个语言区域,当代码尝试获取:de的fallback列表时,返回了nil,而Array#concat只接受数组参数,无法处理nil,所以触发了类型转换错误。

修复方案

方法1:配置全局I18n Fallbacks

在config/application.rb或者专门的I18n配置文件(比如config/initializers/i18n.rb)里添加fallback配置:

# config/initializers/i18n.rb
I18n.default_locale = :de # 如果你的默认语言是德语
I18n.fallbacks.map(:de => :en)
# 或者更通用的配置,让所有非en的语言都fallback到en
I18n.fallbacks = I18n::Locale::Fallbacks.new(:de => :en, :fr => :en, :es => :en)

这样当:de没有对应的翻译时,会自动 fallback 到:en,同时I18n.fallbacks[:de]会返回[:en]而不是nil。

方法2:设置默认Fallback规则

如果你希望所有未配置的语言都fallback到默认语言,可以用更简洁的写法:

# config/initializers/i18n.rb
I18n.default_locale = :de
I18n.fallbacks.defaults = [I18n.default_locale, :en]

或者直接启用全局fallback到默认语言:

I18n.fallbacks = true

这会让任何语言的fallback列表都包含默认语言。

方法3:临时调试(适合开发环境)

如果只是开发环境临时测试,可以在控制台里先手动设置fallback:

I18n.fallbacks[:de] = [:en]

然后再触发Delayed Job任务,确认问题解决后再把配置写到初始化文件里。

验证修复

配置完成后,重启Rails服务器和Delayed Job进程,然后重新执行邮件发送和任务触发命令,检查是否还会出现TypeError。同时可以在控制台验证:

I18n.fallbacks[:de] # 应该返回[:en]或者包含:en的数组,而不是nil

内容的提问来源于stack exchange,提问作者de.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 23:52:41