Dear Russian friends, please watch President Zelenskyy's speech addressed to you. 🇺🇦Help our brave mates in Ukraine with a donation.

Working with schemas

A schema is an object which contains a list of rules that will be applied to its input when you call a schema. It returns a result object which provides an API to retrieve error messages and access to the validation output.

Schema definition best practices:

  • Be specific about the exact shape of the data, define all the keys that you expect to be present
  • Specify optional keys too, even if you don't need additional rules to be applied to their values
  • Specify type specs for all the values
  • Assign schema objects to constants for convenient access
  • Define a base schema for your application with common configuration

Calling a schema

Calling a schema will apply all its rules to the input. High-level rules defined with the rule API are applied in a second step and they are guarded, which means if the values they depend on are not valid, nothing will crash and a high-level rule will not be applied.


schema = Dry::Schema.Params do

result = '', age: 21)

# access validation output data
# => {:email=>'', :age=>21}

# check if all rules passed
# => true

# check if any of the rules failed
# => false

Defining base schema class

class AppSchema < Dry::Schema::Params
  config.messages.load_paths << '/my/app/config/locales/en.yml'
  config.messages.backend = :i18n

  define do
    # define common rules, if any

# now you can build other schemas on top of the base one:
class MySchema < AppSchema
  # define your rules

my_schema =

Working with error messages

The result object returned by Schema#call provides an API to convert error objects to human-friendly messages.

result = nil, age: 21)

# get default errors
# => {:email=>['must be filled']}

# get full errors
result.errors(full: true).to_h
# => {:email=>['email must be filled']}

# get errors in another language
result.errors(locale: :pl).to_h
# => {:email=>['musi być wypełniony']}

Checking presence of errors

You can ask result object if there are any errors under given path.

schema = Dry::Schema.Params do

result = "", tags: ["red", 123])

# => true

# => true

result.error?([:tags, 0])
# => false

result.error?([:tags, 1])
# => true

Learn more

octocatEdit on GitHub