Dry::Validation.Form do
required(:id).filled(:int?)
required(:data).schema do
required(:id).filled(:int?)
end
end
With { id: 1, data: { id: 2 }} it works perfectly, but using the { id: '1', data: { id: '2' }} it will coerce the id in the root but not the one in the data fragment. This makes sense since I’m using a nested schema, not a form. I tried (unsuccessfully):
Dry::Validation.Form do
required(:id).filled(:int?)
required(:data).form do
required(:id).filled(:int?)
end
end
My question is: how can I do a nested form (nested schema coercion + validation)?
This looks like a bug, actually, but I’m not sure if it’s gonna be fixed as we’re moving away from implicit coercions as they will be replaced with explicit type specs.
require 'dry-types'
require 'dry-validation'
puts "dry-types version: #{Dry::Types::VERSION}"
puts "dry-validation version: #{Dry::Validation::VERSION}"
module Types
include Dry::Types.module
end
BookSchema = Dry::Validation.JSON do
required(:publication_date).maybe(:time?)
end
MessageSchema = Dry::Validation.JSON do
required(:book).maybe
required(:type).filled(:str?).when(eql?: 'book') do
required(:book).schema(BookSchema)
end
end
# type conversion works
puts BookSchema.call(publication_date: Time.now.to_s).messages(full: true).inspect
puts BookSchema.call(publication_date: Time.now).messages(full: true).inspect
# type conversion does not work
puts MessageSchema.call(type: 'book', book: { publication_date: Time.now.to_s }).messages(full: true).inspect
puts MessageSchema.call(type: 'book', book: { publication_date: Time.now }).messages(full: true).inspect
Outputs:
dry-types version: 0.13.2
dry-validation version: 0.12.0
{}
{}
{:book=>{:publication_date=>["publication_date must be a time"]}}
{}