Messages
Messages in failure API can be set in 4 different ways:
- By passing a message string explicitly - the simplest way; however, using locales is a cleaner solution even if you don't have a multi-language system
- By passing a message
identifier
that will be used to retrieve a corresponding message template that will be evaluated using provided (optional) data - By passing a hash with message text and arbitrary meta-data - this can be useful when you want to provide additional information in addition to message text, ie error codes etc.
Examples in this section will use
key
failures exclusively, but keep in mind that the exact same API is available when you usebase
failures
Explicit messages
To set a failure message explicitly, pass a message string:
class NewUserContract < Dry::Validation::Contract params do required(:age).value(:integer) end rule(:age) do key.failure('must be greater than 18') if values[:age] < 18 end end contract = NewUserContract.new contract.call(age: 17).errors.to_h # => {:age=>["must be greater than 18"]}
Passing additional meta-data
If you want to set additional meta-data, pass a hash with :text
key:
class NewUserContract < Dry::Validation::Contract params do required(:age).value(:integer) end rule(:age) do key.failure(text: 'must be greater than 18', code: 123) if values[:age] < 18 end end contract = NewUserContract.new contract.call(age: 17).errors.to_h # => {:age=>[{:text=>"must be greater than 18", :code=>123}]}
Using localized messages backend
If you enable the :i18n
or :yaml
messages backend in the configuration, you can define messages in a yaml file and use their identifiers instead of plain strings. Here's a sample yaml with a message for our age
error:
en: dry_validation: errors: rules: age: invalid: 'must be greater than 18'
Provided we configure our contract to use a custom messages file, we can now write this:
class NewUserContract < Dry::Validation::Contract params do required(:age).value(:integer) end rule(:age) do key.failure(:invalid) if values[:age] < 18 end end contract = NewUserContract.new contract.call(age: 17).errors.to_h # => {:age=>["must be greater than 18"]}
Schema messages use the same top-level namespace as rule messages, remember about this if you want to customize messages for schema predicate failures.