-
-
Notifications
You must be signed in to change notification settings - Fork 190
Open
Labels
Description
Describe the bug
When schemas are passed blocks, required field behavior does not always work, and there is inconsistent behavior for reaching validation rules -- although it seems to correlate with whether the required is evaluated.
To Reproduce
class TireSchema < Dry::Schema::JSON
define do
optional(:tread).value(:string, included_in?: %w(offroad allterrain sport road))
optional(:size).value(:integer)
end
end
class SportsCarSchema < Dry::Schema::JSON
define do
optional(:recommended_tire).hash.schema(TireSchema.new) do
optional(:tread).value(:string, included_in?: %w(sport road))
end
end
end
class RaceDriverContract < Dry::Validation::Contract
rule('car.recommended_tire.size') do
puts "The runtime made it to the rule!"
end
json do
required(:car).hash.schema(SportsCarSchema.new) do
required(:recommended_tire).hash.schema(TireSchema.new) do
required(:size).value(:integer)
end
end
end
end
contract = RaceDriverContract.new
contract.call({ car: { recommended_tire: { tread: "invalid value" } } })
# The runtime made it to the rule!
# => #<Dry::Validation::Result{:car=>{:recommended_tire=>{:tread=>"invalid value"}}} errors={:car=>{:recommended_tire=>{:tread=>["must be one of: offroad, allterrain, sport, road"]}}}>
contract.call({ car: { recommended_tire: { tread: "sport" } } })
# => #<Dry::Validation::Result{:car=>{:recommended_tire=>{:tread=>"sport"}}} errors={:car=>{:recommended_tire=>{:size=>["is missing"]}}}>
contract.call({ car: { recommended_tire: { tread: "allterrain" } } })
# The runtime made it to the rule!
# => #<Dry::Validation::Result{:car=>{:recommended_tire=>{:tread=>"allterrain"}}} errors={:car=>{:recommended_tire=>{:tread=>["must be one of: sport, road"]}}}>
Expected behavior
I would expect every one of the above results to contain {:recommended_tire=>{:size=>["is missing"]}, and I would either expect all of them to make it to the rule or none of them to make it to the rule.
My environment
- Affects my production application: YES
- Ruby version: 2.7.2
- OS: macOS 12.0.1 21A559