inheritanceRails i18n子类中的validation错误消息

我明白了什么

假设我有一个方便的validation类,如:

User  {/regex/}, :message => :name_format end 

在这种情况下,我可以使用i18n通过在/config/locals/en.yml包含以下内容来使错误消息可翻译:

 en: activerecord: errors: models: user: attributes: username: name_format: 'has the way-wrong format, bro!' 

这很好,通常非常方便。

我想知道的是什么:

我的问题是:当我有从Userinheritance的子类时会发生什么:

 UserSubclassOne < User # extra stuff end UserSubclassTwo < User # extra stuff end ... UserSubclassEnn < User # extra stuff end 

现在的问题是Rails找不到翻译user_subclass_one.attributes.username.name_format

它抱怨说:

 translation missing: en.activerecord.errors.models.user_subclass_one.attributes.username.name_format 

我希望Rails在UserSubclassOne中搜索字符串时会查找UserSubclassOne的层次结构,然后注意它何时获得“点击”,但是(除非我做了一些可怕的错误)显然不会发生了。

一个显而易见的解决方案是复制en.yml.en.errors.models中的useruser_subclass_oneuser_subclass_two等数据,但我的Rails-sense告诉我这是非常错误的。

任何想法,伙计们?

潜在的并发症:

User在包含在Rails引擎MyEngine中的gem MyGem中定义,该引擎包含在定义UserSubclassOne ,…, UserSubclassEnn的全开Rails应用程序MyApp中。 我不认为这应该是重要的,因为validation是在MyGem::User中运行的,这是en.yml文件所在的en.yml – 只是想让人们知道以防万一。

终极问题/解决方案:

事实certificate问题是命名空间。 回想一下, MyApp (定义UserSubclassOne )使用MyGem (定义User )。 事实certificate, User实际上在命名空间MyGem (这不一定总是如此),因此User开头的完整声明行不是:

 User < ActiveRecord::Base 

反而

 MyGem::User < ActiveRecord::Base 

当i18n gem查找类层次结构时,它会注意到此命名空间并搜索my_gem/user ,而不仅仅是usermy_gem.usermy_gem: user等。

因此,我不得不将我的en.yml文件更改为: /config/locals/en.yml

 en: activerecord: errors: models: my_gem/user: attributes: username: name_format: 'has the way-wrong format, bro!' 

和宾果游戏!

事实certificate问题是命名空间。 回想一下, MyApp (定义UserSubclassOne )使用MyGem (定义User )。 事实certificate, User实际上在命名空间MyGem (这不一定总是如此),因此User开头的完整声明行不是:

 User < ActiveRecord::Base 

反而

 MyGem::User < ActiveRecord::Base 

当i18n gem查找类层次结构时,它会注意到此命名空间并搜索my_gem/user ,而不仅仅是usermy_gem.usermy_gem: user等。

因此,我不得不将我的en.yml文件更改为: /config/locals/en.yml

 en: activerecord: errors: models: my_gem/user: attributes: username: name_format: 'has the way-wrong format, bro!' 

和宾果游戏!

根据针对i18n的Rails指南关于Active Recordvalidation错误消息的错误消息范围(5.1.1) ,您尝试执行的操作应该起作用:

考虑具有name属性validation的User模型,如下所示:

 class User < ActiveRecord::Base validates :name, :presence => true end 

<...剪断...>

当您的模型另外使用inheritance时,将在inheritance链中查找消息。

例如,您可能拥有从Userinheritance的Admin模型:

 class Admin < User validates :name, :presence => true end 

然后Active Record将按以下顺序查找消息:

 activerecord.errors.models.admin.attributes.name.blank activerecord.errors.models.admin.blank activerecord.errors.models.user.attributes.name.blank activerecord.errors.models.user.blank activerecord.errors.messages.blank errors.attributes.name.blank errors.messages.blank 

这样,您可以为模型inheritance链中的不同点以及属性,模型或默认范围中的各种错误消息提供特殊转换。

因此,在您的情况下,假设您的类看起来像这样:

应用程序/模型/ user.rb

 User < ActiveRecord::Base validates :username, :format => {/regex/}, :message => :name_format end 

应用程序/模型/ user_subclass.rb

 UserSubclass < User validates :username, :format => {/regex/}, :message => :name_format end 

你的config / locales / en.yml看起来像:

 en: activerecord: errors: models: user: attributes: username: name_format: 'has the way-wrong format, bro!' 

那么在UserSubClass上搜索validation的消息应该是:

 activerecord.errors.models.user_sublcass.attributes.username.name_format # fail activerecord.errors.models.user_sublcass.name_format # fail activerecord.errors.models.user.attributes.username.name_format # success activerecord.errors.models.user.name_format # ... 

假设您的模型文件和yaml文件看起来与上面的相似,那么您提到的潜在复杂问题可能就是问题,但显然我无法确定。