5

我的理解

假设我有一个带有方便验证的类,例如:

User < ActiveRecord::Base
    validates :username, :format => {/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!'

这很好,通常非常方便。

我想知道的:

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

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在搜索字符串时查找UserSubclassOneto的层次结构,然后注意它何时被“命中”,但是(除非我做错了什么)显然这不会发生。Useren.yml

一个明显的解决方案是复制en.yml.en.errors.modelsfor useruser_subclass_oneuser_subclass_two等中的数据,但我的 Rails 感觉告诉我这是大错特错。

有什么想法吗,伙计们?

潜在并发症:

UserMyGem在包含在 Rails 引擎中的 gem 中定义,该引擎包含在定义, ...,MyEngine的完整 Rails 应用程序中。不过,我认为这并不重要,因为验证正在运行,这是文件所在的位置——只是想让人们知道,以防万一。MyAppUserSubclassOneUserSubclassEnnMyGem::Useren.yml

终极问题/解决方案:

所以事实证明问题出在命名空间上。回想一下MyApp(定义UserSubclassOne)使用MyGem(定义User)。原来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!'

和宾果游戏!

4

2 回答 2

6

所以事实证明问题出在命名空间上。回想一下MyApp(定义UserSubclassOne)使用MyGem(定义User)。原来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!'

和宾果游戏!

于 2013-02-21T19:17:06.723 回答
2

根据关于 Active Record 验证错误消息的错误消息范围 (5.1.1)的 i18n Rails 指南,您尝试执行的操作应该有效:

考虑一个对 name 属性进行验证的 User 模型,如下所示:

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

<...剪辑...>

当您的模型另外使用继承时,则会在继承链中查找消息。

例如,您可能有一个继承自 User 的 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

通过这种方式,您可以在模型继承链以及属性、模型或默认范围的不同点为各种错误消息提供特殊翻译。

所以,在你的情况下,假设你的类看起来像这样:

应用程序/模型/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应该去:

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 文件看起来与上面的相似,那么您提到的潜在并发症可能是问题所在,但显然我不能确定。

于 2013-02-15T04:05:50.917 回答