Whether or not any of the above approaches are buggy, I’ll leave that to project maintainers to decide. I have found a way around the problem, though:
outer_schema = Dry::Schema.Params do
KEYS = %i[ foo ]
before(:value_coercer) { |result|
result.to_h.each_with_object({}) { |(key, value), hash|
hash[key] = KEYS.include?(key) && value == "" ? nil : value
}
required(:foo).maybe(inner_schema)
end
I’m not applying the logic to all keys, as I’ve found it didn’t work with arrays of nested schemas (albeit from very brief testing - I didn’t want to go deep in debugging), so instead I’m just keeping the workaround to where it’s necessary.