-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[BC Break][Validation] Revert #19388 #20857
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
@peterrehm: sorry that this is causing issues for you. However, i think i disagree. Your above code proposal would cause the Therefore I believe #19388 is not a BC Break but the correct fix, and reverting would re-introduce a bug. I have read the docs you linked, do not really understand the heart of your issue. Perhaps you could elaborate? Perhaps we can find a solution that covers both requirements. |
Another way would be
if you want the validation in the same sequence. You should not have an infinite loop there? The PR is a BC break as it now validates some constraints in my case from another group which is not related. Would changing Child to Default work in your case? |
Rethinking it Child should work as well. The docs which I wrote I think state
This means maybe just the implementation of your fix should be updated. Have a look at my issue it provides more info. |
One way to avoid this chaos, is by using 1 object per form type instead of re-using objects for multiple form types. This makes it a lot easier to have validation per object rather than having a chaotic mess of multiple groups per object, especially on entities. |
@iltar But both issues are related to inheritance. There it is hard to avoid. After understanding the validation groups I had never any real issues, especially not with the Default constraint. But now something is just wrong as constraints of other groups are validated. |
@peterrehm regarding
Regarding the quote from the docs:
This sounds legitimate. Perhaps you could create a test case to cover your problem and we can search for a univeral solution? @iltar I think this problem is independent of forms and types and directly related to the validation implementation. The same issues would arise if you do not use the form component at all. |
I will have a look into that next week, I now understand your issue better as it apparently behaves differently in the Group Sequence which I never used. Why do you need sequential validation btw.? I cannot think about a valid use case where you want only errors of the seconf group if the first is passing. |
We have some validation that is pretty process intensive, so we moved it to a second stage in the sequence. If the first part of the sequence is invalid, we get an immediate answer and avoid unnecessary processing |
Form types especially, are about composition over inheritance, that includes the data objects used. |
@iltar that is true. However, this issue is related to validation on entities and not directly with forms. |
Validation on entities is a step too late, your objects (entities) should never even reach an invalid state in the first place. |
But the symfony form/validation concept is based on syncing data to entity and check if valid. What would you recommend? Also I think we talk about a bug rather then about a basic concept. From my experience you need very often different form types for one entity as you have often the need of partial updates. Maybe even a partial update of multiple entities. |
Binding an entity to a form is nothing more than a convenience (at the start): https://stovepipe.systems/post/avoiding-entities-in-forms |
The validation components may be used completely independently from the form components. We often use them without forms to check that objects are in a valid state (e.g. when using a REST API). Also, some objects sometimes have multiple valid or invalid states, and therefore need ways to control such behaviour. With such a model it can be virtually impossible to ensure objects never enter an invalid state (i.e. invalid to who's rules?). It can also lead to overloading value objects with complex business logic and dependencies that would break SRP. @iltar Do you mind if we stay focused on the issue at hand here, rather than theory and rhetoric? |
Okay I have just tried to reproduce your issue here: https://github.com/peterrehm/symfony-standard/commit/d26ff818d88afc0964b40a0882ac78a9139587ba To reproduce the original issue you had in Symfony\Component\Validator\Mapping\ClassMetaData Line 311 needs to be commented. //$member->constraintsByGroup[$this->getDefaultGroup()][] = $constraint; Then the validation shows an error on anotherProperty rather than property as expected. It looks like the issue is that validation in general is broken in case of class inheritance. The docs state:
I checked tried it without the GroupSequence and there the inheritance issue is the same. https://github.com/peterrehm/symfony-standard/commit/bb7206c6da2f7ae0337374a548a495b6c1ea29d1 Back to your fix introduced with #19388. The source here shows that the new implementation is broken since parent constraints are validated ignoring the actual validation group. class ParentClass
{
/**
* @Assert\NotNull(groups={"OtherGroup"})
*/
public $property = null;
}
/**
* @Assert\GroupSequence({"ChildClass", "Extra"})
*/
class ChildClass extends ParentClass
{
/**
* @Assert\NotNull(groups={"Extra"})
*/
public $anotherProperty = null;
} If you validate ChildClass you still get an error on So in conclusion I think the PR should be reverted and we need to find a way to fix inheritance in the validation as the behavior stated in the docs is the expected one. |
Okay, so the solution gets more difficult.
Maybe this is just a documentation error, I just recall that I had lengthy discussions with several people back then. @weaverryan Can you recall what was intended?
Rethinking the current implementation if I have the inheritance of Parent and Child as discussed so far, the only way to split validation is with the current implementation.
However the issue for the GroupSequence persists as the docs state that the default group is overwritten. In any case what we do and as well as #19388 has major implications. |
Correct. The issue is I could not find anything regarding the inheritance in the code itself. Changing the inheritance validation function is IMHO a BC break and only a solution is really needed for the GroupSequence as to my understanding in the GroupSequence the Default constraint is not available. ping @symfony/deciders |
I'm inclined to agree with you. We should not change the inheritance rules, as that indeed causes a BC break (and they also make sense). The issue is therefore with the group sequence assuming the I would propose to unify the syntax and allow |
Okay, so we agree to revert the changes as this is really a problem. However theoretically allowing With this implementation and the inheritance you get the tree validated for the Default Group anyway and the GroupSequence is just one constraint in the default group which gets executed after the first run. We should fix the BC break asap and then try to find a solution for the GroupSequence. I also just wrote a mail to Bernhard to figure out the intention regarding inheritance. |
Since a change now would cause breaks to code for many different people, i would prefer if we could reach a decicion of how the group sequence problem should be handled before any hasty changes are made. |
@yakobe I think at first we should revert the code and then we can look for a solution. You still should be able to run
with no real issues. On the other side there is no workaround at the moment, we had to patch symfony in one app. I am sure that more people will complain in the future after upgrades as this is a hard to catch issue. @HeahDude what do you think as you approved the original PR? |
@peterrehm You're right, I should not have approved that BC break in the first place. 👍 for reverting though. Again, sorry and thank you @peterrehm. |
Ok, good stuff. That's one half of the issue agreed. |
@HeahDude What do you mean by solving with using Parent instead of Child? If you use Parent then the Child constraints are not validated. As Default is overwritten in that Context it looks like there is no way to validate the entire inheritance. @yakobe Is there an issue with validating them Sequentially like Parent, Child and then Extra? Still I think having a way to validate the entire tree might be good though. |
@peterrehm I mean reading IMHO using a new alias for What could actually work is to use internally some internal constants, just throwing the idea: Validation::DEFAULT_GROUP = 'Default';
Validation::DEFAULT_SEQUENCE = '__Default_Sequence__'; So keeping the |
Or, we could not put the sequence in the |
@peterrehm yes, splitting the validation sequence into parent and child would not be ideal, epecially with some horrible multi-level inheritance situations. It would be best to just 'run the default' |
Or another way might be allowing Default in the GroupSequence (No BC Break as it was not used before) but the logic will need to be updated to avoid the infinite loop. |
@peterrehm Maybe you've misunderstood my proposal:
Using internal constants to "translate" |
Oh actually I meant the same, I am just not yet sure what is the best way. But it would be best to allow Default within GroupSequence and to work around that. |
Isn't it possible already to use the |
To avoid confusion from my comment above, here's what I mean:
|
I think there is no easy fix in this regards looking at the implementation in the |
This PR was submitted for the 2.8 branch but it was merged into the 2.7 branch instead (closes #7249). Discussion ---------- [Validator] Fixed wrong inheritance information There is wrong information about the inheritance of validation groups. I have tested it extensively and some findings are documented here: symfony/symfony#20857 I also asked Bernhard about what the intended behavior is, but I assume as I have documented it now was the original expected behaviour. Commits ------- 49dfdf4 Fixed wrong inheritance information
Let's close here as well now that #21183 is merged. Thanks @peterrehm |
I recommend to revert #19388 in order to fix a BC break introduced therefore.
Looking at #19387 it looks like there might be a misunderstanding of the validation groups.
I had a intense discussion with Bernhard here #11880 about the validation groups. Also I proposed a dynamic validation solution here #16984.
I think in order to solve #19387 only this might be needed:
Also it looks like a good use case for my Dynamic Validation Group as I think in many cases you do not want a sequential validation you want to see the validation result of all groups right away.
For more information about validation groups see https://symfony.com/doc/current/validation/groups.html