Decimal fields are not casted from integer/float

Hey.
In dry-validation 0.13 I used to send decimal values like 12 or 12.45 and they were casted to decimal by the library. Why is that no longer a case in 1.2.1?

[28] pry(main)> class TestContract < ApplicationContract
[28] pry(main)*   params do
[28] pry(main)*     required(:test).filled(:decimal?)
[28] pry(main)*   end
[28] pry(main)* end
=> #<Dry::Schema::Params keys=["test"] rules={:test=>"key?(:test) AND key[test](filled? AND 
decimal?)"}>
[29] pry(main)> TestContract.new.call(test: 1)
=> #<Dry::Validation::Result{:test=>1} errors={:test=>["must be a decimal"]}>
[30] pry(main)> TestContract.new.call(test: 1.1)
=> #<Dry::Validation::Result{:test=>1.1} errors={:test=>["must be a decimal"]}>
[31] pry(main)> TestContract.new.call(test: '1.1')
=> #<Dry::Validation::Result{:test=>"1.1"} errors={:test=>["must be a decimal"]}>
[32] pry(main)> TestContract.new.call(test: '1.1'.to_d)
=> #<Dry::Validation::Result{:test=>0.11e1} errors={}>
[33] pry(main)> TestContract.new.call(test: 1.1.to_d)
=> #<Dry::Validation::Result{:test=>0.11e1} errors={}>

Moreover, Dry::Types coerce it properly:

[35] pry(main)> Types::Params::Decimal[1]
=> 0.1e1

EDIT: It also stopped working for :bool? check on strings: "true" or "false"

For now I’ve fixed it with:

class Test < ApplicationContract
  params do
    required(:test).filled(Types::Params::Decimal)
  end
end

I don’t like this solutions, though. Any ideas how to bring back the old functionality?

In dry-validation 1.0, you want to supply a type spec as the first argument, and the matching predicate will be inferred from it, so e.g.

required(:test).filled(:decimal)

In my testing:

dry-validation> class Test < Dry::Validation::Contract
dry-validation*>   params do  
dry-validation*>     required(:test).filled(:decimal)    
dry-validation*>   end    
dry-validation*> end  

dry-validation> Test.new.("test" => "1.2")
=> #<Dry::Validation::Result{:test=>0.12e1} errors={}>

That would be the behaviour you want, right?

2 Likes

Neat. That’s exactly the behaviour I want. Thank you, sir :slight_smile: