trailblazer / reform

Form objects decoupled from models.
https://trailblazer.to/2.1/docs/reform.html
MIT License
2.5k stars 184 forks source link

Dry Validation hints are included in Reform::Contract::Errors #444

Open grizzlydev opened 7 years ago

grizzlydev commented 7 years ago

Complete Description of Issue

Reform/ Dry integration takes the whole Dry::Validation::Result#messages (hints + errors), not just errors. Consequently hints are presented indistinguishable from actual errors. If you have two predicates which validate the same nature of an input (e.g. less than + greater than on an int) this leads to a bad user experience - users are told something is failing when it is not.

Steps to reproduce

  class PersonForm < Reform::Form
    property :name

    property :age

    validation do 
      required(:name).filled

      required(:age).filled(:int?, gt?: 18, lt?: 70)
    end 
  end
  PersonModel = Struct.new(:name, :age)
  form = PersonForm.new(PersonModel.new)
  result = form.validate({
    name: 'joe bloggs',
    age: 17
  })

Expected behavior

Tell us what should happen

# result.errors is {:age=>["must be greater than 18"]}

Actual behavior

Tell us what happens instead

# result.errors is {:age=>["must be greater than 18", "must be less than 70"]}

System configuration

Reform version:2.2.4

Full Backtrace of Exception (if any)

N/A

apotonick commented 7 years ago

Cool, I finally understood the difference and what's a hint, now!

fran-worley commented 7 years ago

@apotonick if you look back at the old code I put together for 2.3.1 I had a handle for this.

We have to be careful how we do it as if you run separate calls to dry-v's error messages object (say to get errors and hints separately) it'll build the errors twice.