trailblazer / reform

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

Form returns merged errors for `collection` after validation #521

Closed Svatok closed 3 years ago

Svatok commented 4 years ago

Complete Description of Issue

Form returns merged errors for collection after validation.

Steps to reproduce

Run test:

# error messages for collection
class ValidateCollectionTest < MiniTest::Spec
  class AlbumForm < TestForm
    collection :songs do
      property :title

      validation do
        params do
          required(:title).filled(min_size?: 2, max_size?: 5)
        end
      end
    end
  end

  let(:song)               { Song.new("Broken") }
  let(:song_with_composer) { Song.new("Resist Stance", nil, composer) }
  let(:composer)           { Artist.new("Greg Graffin") }
  let(:artist)             { Artist.new("Bad Religion") }
  let(:album)              { Album.new("The Dissent Of Man", [song, song_with_composer], artist) }

  let(:form) { AlbumForm.new(album) }

  let(:expected_errors) do
    {
      songs: [
        [0, { title: ['size cannot be greater than 5'] }],
        [1, { title: ['size cannot be less than 2'] }]
      ]
    }
  end

  it do
    # Actual result is:
    # {:"songs.title"=>["size cannot be less than 2", "size cannot be greater than 5"]}
    form.validate("songs"  => [{"title" => "Roxanne"}, {"title" => "F"}])
    assert_equal expected_errors, form.errors.messages
  end
end

Expected behavior

Test is passed.

Actual behavior

Test is failed. Form returns merged errors: {:"songs.title"=>["size cannot be less than 2", "size cannot be greater than 5"]}

System configuration

Reform version: v2.4.0 dry-validation version: v1.5.2

yogeshjain999 commented 3 years ago

@Svatok That's the expected behaviour. form.errors.messages gives errors for only the top level properties/collections combined. collection creates separate reform object which can be iterated over to get their errors, just like has_many which is also compatible to form_for or any form tag.

See - https://github.com/trailblazer/reform/blob/master/test/validation/dry_validation_test.rb#L460

Formatting nested errors is upto you as few wants them in array style or in dotted ("songs.0.title") style.