Error Messages
By default dry-validation
comes with a set of pre-defined error messages for every built-in predicate. They are defined in a yaml file which is shipped with the gem. This file is compatible with I18n
format.
You can provide your own messages and configure your schemas to use it like that:
schema = Dry::Validation.Schema do
configure { config.messages_file = '/path/to/my/errors.yml' }
end
You can also provide a namespace per-schema that will be used by default:
schema = Dry::Validation.Schema do
configure { config.namespace = :user }
end
Lookup rules:
en:
errors:
size?:
arg:
default: "size must be %{num}"
range: "size must be within %{left} - %{right}"
value:
string:
arg:
default: "length must be %{num}"
range: "length must be within %{left} - %{right}"
filled?: "must be filled"
included_in?: "must be one of %{list}"
excluded_from?: "must not be one of: %{list}"
rules:
email:
filled?: "the email is missing"
user:
filled?: "name cannot be blank"
rules:
address:
filled?: "You gotta tell us where you live"
Given the yaml file above, messages lookup works as follows:
messages = Dry::Validation::Messages::YAML.load(%w(/path/to/our/errors.yml))
# matching arg type for size? predicate
messages[:size?, rule: :name, arg_type: Fixnum] # => "size must be %{num}"
messages[:size?, rule: :name, arg_type: Range] # => "size must be within %{left} - %{right}"
# matching val type for size? predicate
messages[:size?, rule: :name, val_type: String] # => "length must be %{num}"
# matching predicate
messages[:filled?, rule: :age] # => "must be filled"
messages[:filled?, rule: :address] # => "must be filled"
# matching predicate for a specific rule
messages[:filled?, rule: :email] # => "the email is missing"
# with namespaced messages
user_messages = messages.namespaced(:user)
user_messages[:filled?, rule: :age] # "cannot be blank"
user_messages[:filled?, rule: :address] # "You gotta tell us where you live"
By configuring messages_file
and/or namespace
in a schema, default messages are going to be automatically merged with your overrides and/or namespaced.
I18n Integration
If you are using i18n
gem and load it before dry-validation
then you'll be able to configure a schema to use i18n
messages:
require 'i18n'
require 'dry-validation'
schema = Dry::Validation.Schema do
configure { config.messages = :i18n }
required(:email).filled
end
# return default translations
schema.call(email: '').messages
{ :email => ["must be filled"] }
# return other translations (assuming you have it :))
puts schema.call(email: '').messages(locale: :pl)
{ :email => ["musi być wypełniony"] }
Important: I18n must be initialized before using a schema, dry-validation
does not try to do it for you, it only sets its default error translations automatically.
Full Messages
By default, messages do not include a rule's name, if you want it to be included simply use :full
option:
schema.call(email: '').messages(full: true)
{ :email => ["email must be filled"] }
Finding the right key
dry-validation
has one error key for each kind of validation (Refer to errors.yml
for the full list). key?
and filled?
can usually be mistaken for eachother, so pay attention to them:
key?
: a required parameter is missing in theparams
hash.filled?
: a required parameter is in theparams
hash but has an empty value.