Handling Nested forms


#1

This is my form:

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)?


#2

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.


#3

I have the same problem :frowning: Any news here?

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"]}}
{}