Skip to content

[Form] Errors Property Paths mismatch CollectionType children when removing an entry #39438

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

cristoforocervino
Copy link
Contributor

@cristoforocervino cristoforocervino commented Dec 10, 2020

Q A
Branch? 7.1
Bug fix? no
New feature? yes
Deprecations? no
Tickets -
License MIT
Doc PR -

Description
When you remove an entry from CollectionType and you have errors on children, errors property paths generated by ValidatorExtension are matching final object collection indexes but do not match From children entries index/names.

How to reproduce
Unit test provided.

Solution
Introduce new feature with keep_as_list (boolean default to false) option to reindex children on submit.

@carsonbot
Copy link

Hey!

I didn't know that was capable of this emotion. I really really like reviewing this PR. Well done.

To help keep things organized, we don't allow "Draft" pull requests. Could you please click the "ready for review" button or close this PR and open a new one when you are done?

Note that a pull request does not have to be "perfect" or "ready for merge" when you first open it. We just want it to be ready for a first review.

Cheers!

Carsonbot

@cristoforocervino cristoforocervino marked this pull request as ready for review December 10, 2020 19:15
@carsonbot carsonbot added this to the 4.4 milestone Dec 10, 2020
@cristoforocervino cristoforocervino force-pushed the form-collection-type-errors-property-paths-mismatch branch from a435596 to dc5e0b2 Compare December 10, 2020 19:16
@xabbuh
Copy link
Member

xabbuh commented Jan 12, 2021

@StevioStudio Sorry, your PR somehow slipped through. Thank you for taking the time to create a failing test case. That's really appreciated. 👍 I will try to look into a possible fix soon.

@xabbuh
Copy link
Member

xabbuh commented Jan 17, 2021

As your test also asserts the entry form types of the collection type are not renamed. So after submitting we only have entry types named 0, 2, and 3. However, due to how removeAuthor() is implemented the submitted data is mapped to an indexed array. Thus when the form is displayed again, we now have data indexed with 0, 1, and 2 while the form still has 0, 2, 3.

With the current implementation I do not see how we can actually fix this as inside the ResizeFormListener we do not know whether or not the index is important.

For your project I see two possible workarounds:

  • Change the implementation in your model class to not reindex the collection when the form data is mapped back (which might not be suitable depending on how you deal with the data).
  • Register a custom event listener that runs after the built-in ResizeFormListener and changes the form names.

@cristoforocervino
Copy link
Contributor Author

For your project I see two possible workarounds:

  • Change the implementation in your model class to not reindex the collection when the form data is mapped back (which might not be suitable depending on how you deal with the data).
  • Register a custom event listener that runs after the built-in ResizeFormListener and changes the form names.

Wait, this is not only related to the model I'm using in this unit test.
CollectionType is usually used with Doctrine Collections. Doctrine collections removeElement method also reindex the collection the same way. Shouldn't Symfony Form at least provide an option to handle this (common) situation?

@xabbuh
Copy link
Member

xabbuh commented Jan 17, 2021

While I agree I don't see a way to fix this without introducing a new option (like proposed in #7828). So that would go into a future minor version instead of a patch release.

By the way, is it really a common use case to use the CollectionType with Doctrine entities? What are the use case where the EntityType isn't sufficient?

@cristoforocervino
Copy link
Contributor Author

cristoforocervino commented Jan 17, 2021

Well, you know that CollectionType and EntityType are meant to handle completely different situations.
I do not have numbers or statistics to show you, but it's pretty common, for example, to have a CollectionType with the option entry_type set to EntityType.

I think the new option with a minor version release could be a good idea.
Like a sequential_keys option set to false by default.
If sequential_keys is set to true, ResizeFormListener is going to handle a situation like the one described by my unit test in the right way.

What do you think?

@xabbuh
Copy link
Member

xabbuh commented Jan 18, 2021

I have a feature like that on my to-do list. Though not sure when I will find the time for it. Hopefully it will make it to 5.3.

@cristoforocervino cristoforocervino force-pushed the form-collection-type-errors-property-paths-mismatch branch from 88d307e to a4462c8 Compare January 18, 2021 20:30
@cristoforocervino
Copy link
Contributor Author

I came up with a new reindex_on_submit boolean option set to false by default.
I updated code and test. What do you think? Did you have in mind something different?

@cristoforocervino cristoforocervino force-pushed the form-collection-type-errors-property-paths-mismatch branch from a4462c8 to 2cad8ee Compare April 13, 2021 18:16
@cristoforocervino cristoforocervino changed the base branch from 4.4 to 5.x April 13, 2021 18:18
@cristoforocervino
Copy link
Contributor Author

This PR initially started as a bug fix with unit test provided to explain the issue.
I changed it into a new feature by introducing a new keep_as_list option for CollectionType.
I'm still open to suggestions on how to improve this code and find the right way to solve the highlighted issue.

@fabpot fabpot modified the milestones: 4.4, 5.4 Aug 26, 2021
@fabpot fabpot modified the milestones: 5.4, 6.1 Oct 30, 2021
@andimg93
Copy link

andimg93 commented Apr 1, 2022

@xabbuh, @yceruto, @chalasr, @dunglas, @jderusse, @lyrixx, @sroze, @wouterj
Please look into that issue fix, there are so many issues that all trace back to this bug and have been around since 2013 - it's really important, even if it's annoying to ask for focus here. Without a solution collections are simply not decently usable, it can and must not be a solution to re-index it all via javascript (frontend). Simply that you can't find a nice solution here (frontend based), but have to search out the individual parts via regex.

The real solution must be in the backend, because it is simply a bug and not a feature.

@fabpot fabpot modified the milestones: 6.1, 6.2 May 20, 2022
@nicolas-grekas nicolas-grekas modified the milestones: 6.2, 6.3 Nov 5, 2022
@nicolas-grekas nicolas-grekas modified the milestones: 6.3, 6.4 May 23, 2023
@nicolas-grekas nicolas-grekas modified the milestones: 6.4, 7.1 Nov 15, 2023
Copy link
Contributor

@HeahDude HeahDude left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not against a new opt-in feature for this but we should be careful when documenting it.
Indeed, such behavior depends on how the collection type data is mapped to the parent object.
In other words, how the adder and remover are implemented in the holder of the collection impact indexes without being able to send feedback to the collection type when going back to the view with errors.
Sadly after discussing this issue with @stof, we cannot think of another way to work around that efficiently, since the PropertyAccess does not allow to set specific indexes when calling adders and removers.

//In fact, root form should NOT contain errors but it does
$this->assertCount(1, $form->getErrors(false));

//Let's do this again, but with "keep_as_list" option set to true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you create another test method instead of grouping two tests in the same one please?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also need a rebase and to update the changelog.
Please tell us if you want to do it or if we should take over, thank you.

@cristoforocervino cristoforocervino force-pushed the form-collection-type-errors-property-paths-mismatch branch from 94bae4d to 70e1b0e Compare December 9, 2023 11:53
@OskarStark OskarStark modified the milestones: 6.4, 7.1 Dec 9, 2023
@OskarStark OskarStark added Feature and removed Bug labels Dec 9, 2023
@cristoforocervino cristoforocervino force-pushed the form-collection-type-errors-property-paths-mismatch branch from 70e1b0e to fff25e3 Compare December 9, 2023 12:34
Copy link
Contributor

@HeahDude HeahDude left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to make fabbot happy fixing the CS and update the Form component CHANGELOG please. Thanks

@cristoforocervino cristoforocervino force-pushed the form-collection-type-errors-property-paths-mismatch branch from fff25e3 to f31de2b Compare December 9, 2023 13:18
@fabpot fabpot force-pushed the form-collection-type-errors-property-paths-mismatch branch from f31de2b to 39587cb Compare December 9, 2023 14:28
@fabpot
Copy link
Member

fabpot commented Dec 9, 2023

Thank you @cristoforocervino.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants