dry-validation icon indicating copy to clipboard operation
dry-validation copied to clipboard

`Dry::Validation::Contract` behaves different when defined with a `params Dry::Schema::Params(parent: RawSchema)` vs. `params ParamsSchema`

Open postmodern opened this issue 1 year ago • 2 comments

Describe the bug

When Dry::Validation::Contract contains params Dry::Schema::Params(parent: RawSchema) (where RawSchema is defined using Dry::Schema.define do ... end), it fails to coerce empty Strings into Integers. However, if I define a ParamsSchema using Dry::Schema::Params() do ... end containing the same param definitions, and add params ParamsSchema to my Dry::Validation::Contract class, it works as expected.

To Reproduce

require 'dry/types'
require 'dry/schema'
require 'dry/validation'

module Types
  include Dry::Types()
end

RawSchema = Dry::Schema.define do
  required(:foo).filled(:string)
  optional(:bar).maybe(:integer)
end

ParamsSchema = Dry::Schema::Params() do
  required(:foo).filled(:string)
  optional(:bar).maybe(:integer)
end

class WrappedParamsSchemaValidation < Dry::Validation::Contract

  params Dry::Schema::Params(parent: RawSchema)

end

class ParamsSchemaValidation < Dry::Validation::Contract

  params ParamsSchema

end

params = {"foo" => "a", "bar" => ""}

p WrappedParamsSchemaValidation.new.call(params)
p ParamsSchemaValidation.new.call(params)

Expected behavior

#<Dry::Validation::Result{:foo=>"a", :bar=>nil} errors={}>
#<Dry::Validation::Result{:foo=>"a", :bar=>nil} errors={}>

Actual behavior

#<Dry::Validation::Result{:foo=>"a", :bar=>""} errors={:bar=>["must be an integer"]}>
#<Dry::Validation::Result{:foo=>"a", :bar=>nil} errors={}>

My environment

  • Affects my production application: NO (the app is not running in production)
  • Ruby version: ruby 3.1.3p185 (2022-11-24 revision 1a6b16756e) [x86_64-linux]
  • dry-types: 1.7.1
  • dry-schema: 1.13.1
  • dry-validation: 1.10.0

postmodern avatar Apr 07 '23 21:04 postmodern