Inheriting Rails i18n validation error messages in the subclass
i18n-gem, inheritance, rails-i18n, ruby-on-rails, validation
Solution
So it turns out that the problem was namespacing. Recall that `MyApp` (which defines `UserSubclassOne`) uses `MyGem` (which defines `User`). It turns out `User` is actually in the namespace `MyGem` (this is not necessarily always the case), so the full declaration line at the beginning of `User` is not:
User < ActiveRecord::Base
but rather
MyGem::User < ActiveRecord::Base
.
When the i18n gem looks up the class hierarchy, it notices this namespace and searches for `my_gem/user`, rather than simply `user`, `my_gem.user`, `my_gem: user`, etc.
Thus I had to change my `en.yml` file to: `/config/locals/en.yml`:
en:
activerecord:
errors:
models:
my_gem/user:
attributes:
username:
name_format: 'has the way-wrong format, bro!'
and bingo!
Problem
What I understand Suppose I have a class with a handy validation like: ``` User < ActiveRecord::Base validates :username, :format => {/regex/}, :message => :name_format end ``` In this case, I can use `i18n` to make the error message translatable, by including the following in my `/config/locals/en.yml`: ``` en: activerecord: errors: models: user: attributes: username: name_format: 'has the way-wrong format, bro!' ``` This is fine and generally really handy. What I want to know: My question is: What happens when I have subclasses that inherit from User: ``` UserSubclassOne < User # extra stuff end UserSubclassTwo < User # extra stuff end ... UserSubclassEnn < User # extra stuff end ``` Now the problem is that Rails can't find the translation `user_subclass_one.attributes.username.name_format`. It complains: ``` translation missing: en.activerecord.errors.models.user_subclass_one.attributes.username.name_format ``` I'd hope that Rails would look up the hierarchy of `UserSubclassOne` to `User` when searching for a string in `en.yml` and then notice when it gets a 'hit', but (unless I've done something horribly wrong) apparently that doesn't happen. An obvious solution is to duplicate the data in `en.yml.en.errors.models` for `user`, `user_subclass_one`, `user_subclass_two`, etc, but my Rails-sense tells me that this is deeply wrong. Any ideas, folks? Potential Complication: `User` is defined in a gem `MyGem` that is included in a Rails engine `MyEngine` that is included in the full-on Rails app `MyApp` that defines `UserSubclassOne`, ..., `UserSubclassEnn`. I don't think this should matter though, since the validations are running in `MyGem::User`, which is where the `en.yml` file lives -- just wanted to let people know in case it does. Ultimate problem/solution: So it turns out that the problem was namespacing. Recall that `MyApp` (which defines `UserSubclassOne`) uses `MyGem` (which defines `User`). It turns out `User` is actually in the namespace `MyGem` (this is not necessarily always the case), so the full declaration line at the beginning of `User` is not: ``` User < ActiveRecord::Base ``` but rather ``` MyGem::User < ActiveRecord::Base ``` . When the i18n gem looks up the class hierarchy, it notices this namespace and searches for `my_gem/user`, rather than simply `user`, `my_gem.user`, `my_gem: user`, etc. Thus I had to change my `en.yml` file to: `/config/locals/en.yml`: ``` en: activerecord: errors: models: my_gem/user: attributes: username: name_format: 'has the way-wrong format, bro!' ``` and bingo!