Rails:嵌套模型名称无法通过i18n翻译?求解决方案
我之前也踩过ActiveRecord关联验证消息的坑,这种重复显示模型名的问题确实容易让人摸不着头脑。让我帮你拆解问题根源,再给出两种实用的解决方案:
问题根源
你在Company模型里验证signatories(has_many关联)时,ActiveRecord默认会把这个属性的人性化名称设置为关联模型的单数名(也就是Signatory),然后自动将这个名称前缀到你的自定义消息前。而你的消息里已经写了"Signatories...",就导致了"Signatory Signatories should have..."这种重复的尴尬情况。
另外要说明的是:你之前配置的company/signatory是给嵌套属性(比如accepts_nested_attributes_for场景)用的,和当前关联集合的验证无关;signatory模型的one/other配置是用于模型名称的复数化计数(比如显示"2 Signatories"),也不会影响关联属性的验证消息前缀。
解决方案1:修正属性显示名+简洁消息
这种方法保留ActiveRecord的默认消息格式,同时让显示内容完全符合预期:
- 在
en.yml中为Company模型的signatories属性指定复数显示名:
en: activerecord: models: company: Company signatory: one: Signatory other: Signatories attributes: company: signatories: "Signatories" # 明确指定属性的显示名称为复数
- 修改验证代码,去掉消息开头重复的"Signatories":
validates :signatories, length: { minimum: 1, message: _("should have at least one authorized signatory") }
最终生成的错误消息就是:"Signatories should have at least one authorized signatory",完全符合需求。
解决方案2:自定义完整错误消息(无自动前缀)
如果你想直接定义整个错误消息,不想依赖ActiveRecord的前缀逻辑,可以精准针对这个验证场景配置:
- 在
en.yml中添加too_short类型的完整自定义消息(minimum:1触发的就是too_short错误):
en: activerecord: models: company: Company signatory: one: Signatory other: Signatories errors: models: company: attributes: signatories: too_short: "Signatories should have at least one authorized signatory"
- 简化验证代码,不再手动指定
message:
validates :signatories, length: { minimum: 1 }
这样ActiveRecord会直接读取你定义的完整消息,不会再添加多余的属性名称前缀,也不会影响其他错误消息的格式。
内容的提问来源于stack exchange,提问作者Michael Schmitz

