Dig into the rails errors
Errors
Rails errors is handling by ActiveModel::Errors, which generate error messages with attribute name and error type.
Recently I am working on some feature related to rails error messages, so it is a good time to go over how the rails errors works.
It’s just a hash
ActiveModel::Errors actually is a wrapper for error messages hash, which include the attribute names and error messages for attributes.
So we can start with understand what does this wrapper do, ActiveModel::Errors provides 3 basic functionality:
- Provides ‘add’ method that takes attribute name and error type
- Translate error types to error messages by Rails i18n module.
- Provides Enumerable Api like each for traversing.
Lets take those and make a minimun implementation:
1 |
|
How does ActiveModel::Errors generate the error message?
The most confusing part in ActiveRecord::Errors is how the error message got generated and how to customize it.
When generating the message, it creates keys with attribute name and error type,
pass the attribute, value and keys to I18N.translate. When translation is missing,
I18n will lookup the next possible key in keys provided.
Here is the code from ActiveModel::Errors
1 |
|
Details for the win - in Rails 5
However, the previous implementaion is hard to customize when you need something like links in the error message.
In rails 5, it provide an API called ‘details’ which return the errors hash, but with original error type but not generated message:
Pull Request
model = User.first
errors = ActiveModel::Errors.new(model)
errors.add(:name, :invalid)
errors.messages
# => {name: ['is invalid']}
errors.details
# => {name: [:invalid]}
Let user can generate different error message in different context.
Right now we can install the gem to get the backported feature in Rails 4.x:
# in gemfile
gem 'active_model-errors_details'
With this gem, we can finally generate custom error message in different places without complex structure.
Comments