Rails 2.3.5 introduced support for lazy translations of ActiveRecord validation messages. This enabled various features that are required when you need consistent I18n support for these messages.
These changes never got ported to ActiveModel and ActiveRecord 3.0.0beta1 is based on ActiveModel. So Rails 3.0.0.beta1 does not include the changes either. Thus Rails 3 was forced to either break backwards compatibility for either ActiveRecord or ActiveModel. Because the implementation of mentioned changes in ActiveRecord 2.3.5 was kind of flaky anyway (at that point backwards compatibility alread had to be taken into account) the former option was chosen.
So instead of trying to fit these changes into ActiveModel we’ve gone back to the drawing board and came up with a fresh and clean implementation of what surfaced as relevant features in our previous attemps. This situation now allows us to (again) experiment with features and implementations way more freely, check out concurring implementations and possibly cherry-pick the best of breed for re-inclusion into Rails.
Our current goal is to provide backwards compatibility and a usable legacy API for validation message I18n in ActiveRecord and ActiveModel.
Once this is done we might dive into making features optional and fixing some of the flaws that were in ActiveRecord 2.3.5 and still are in ActiveModel 3.0.0beta1.
By “usable legacy API” we refer to the following requirements:
- Messages in class method calls (such as
validates_presence_of
) are treated as plain text by default (users might optionally want to treat them as translation keys for gettext-style class method calls). - Symbols in class method calls are treated as translation keys.
- Settings in from class method calls are used consistently with translation keys that are implicitly used for a particular validation.
- Different translation variants (such as
:full_message
) for the same message are possible. - Translation calls are able to cascade over scopes.
- Format strings like
"{{attribute}} {{message}}"
are supported transparently
Just install the gem
gem install activemodel-error
and require activemodel_error
somewhere in your application.
The class ActiveModel::Error
class is the meant to work as a default error class in ActiveModel. The implementation is based on I18n::Message. Please see the README for an explanation of the features provided. ActiveModel::Error
inherits from I18n::Message
and basically adds a few customizations that are required to achieve the expected behavior.
We also monkeypatch ActiveModel::Errors
so that it keeps a collection of ActiveModel::Error
instances which then can be translated, formatted and otherwise altered at any point of time (instead of directly translating them and only keeping translations as Strings).
TODO
- add a Usage section and describe the API in detail
- add a note about core_ext/error_comparsion.rb