-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Form][Validator] Embedded entities are validated with the wrong validation groups #30094
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
Comments
Thank you for providing this great example that easily allowed to reproduce the bug. The underlying issue is that the Status: Reviewed |
Thank you for taking your time reviewing this issue @xabbuh. Is there anything we can do from our side, like providing some man-power and digging through the code? Or do you happen to know whether there's someone (inside SensioLabs) that might have an initial clue and can start digging? Either way, I'm more than happy to help as much as I can |
@xabbuh are you saying that the FormB validation groups shouldn’t be resolved at all? Which validation groups would they use then? Because as I read this issue it is indeed correct that both validation_groups are resolved (to a different set of groups, which is an important feature), but the „only“ bug seems to be that the validation group of the nested forms are resolved after the entity is validated. So we would just have to fix the order of the actions. This is an important use case, that the nested form can have separate validation groups. Because that is needed for implementing a reusable entity (think of a generic doctrine relation or even an embeddable) that has a default form but some optional (depending on the data of this embedded entity) validation groups. |
According to the documentation the But that is only based on what I can deduct from the existing documentation (I talked with @HeahDude about this too and he had the same impression). From the git history I wasn't able to find any information about the expected behaviour. |
Hm, interesting. Yes, I see your point. I'm wondering what the rationale behind this decision might be and whether it's time to rethink that decision, as it seems logical and more flexible to validate each entity with the corresponding form's I'm kinda advocating for a new form option to allow validating each embedded entity with the corresponding validation groups, as this seems like the only non-BC-breaking way to achieve this behaviour, without having to do validation manually inside the controller. Any opinions? |
@xabbuh irregardless of the original intention, the point I am thinking about is this one:
Nope, at least I don't know a way.
Yes, you should be able to just pass the validation groups explicitly to the child: class RootForm extends AbstractType
{
public function buildForm (FormBuilderInterface $builder, array $options)
{
$builder->add("test", NestedForm::class, [
"validation_groups" => $options["validation_groups"],
]);
}
} So I would go with version 2, as this enables both and version 1 leads to inflexibility. Or am I missing something? |
Well, IMO the example application shows a clear sign of why the current behaviour is not so clear. But when it comes to also validating the nested So what is the correct behaviour here? Which is the source of truth? If you use the Validator as a stand-alone component, this behaviour is clear. Groups are passed when the validation process is started. Here the behaviour currently is different and probably that's why the option was meant to be used only on root forms. |
The only issue I currently see is that the
and IMO what should happen:
Everything else would (again IMO) hugely limit the benefit of reusable nested forms, as we always have to move the logic like "do we need to validate this one property as well?" to all including parent forms (which sort-of violates SRP). wdyt? |
The solution you propose means that the validator would have to know that there is another branch when traversing the graph that will validate the |
Oh, you are right. Thanks, I didn’t think about both of them in isolation, what I would need to do of course. However the use case still stands: for reusable forms with reusable entities we need to be able to set them dynamically. Would it make sense to let nested forms append to the list of validation groups of the root form? So
That might work and could be a compromise? |
I don't think this will work either. You may have defined some validation groups only in nodes of your form tree that handle only some attributes of your entity. If we were to merge the groups of all forms, that would mean that we were now validating the whole entity with all these groups. |
I encountered a simmilar behavior and was confused by it so I did some debugging. It works this way: After validation of root form data it validates root form and its children recursively against constraints defined using form options (and groups of the form it validates). So it also encounters field But if I was also confused by this but is it actually a bug? |
There is a solution for @keichinger problem. First of all, we must distinguish between the The data class has its own constraints which validate that it is in a proper state. The data class will be validated before validating the root form and with the groups of the root form. There is no other way to set up groups to validate the data class. If we have a special method that should be executed only inside the form, we must specify a group for this method. For example: Now, if we add If we add So, we can
P.S. This issue is not a bug. False expectations regarding the validation order arise due to a misunderstanding of the behavior of the data class and form fields during validation. |
As the comments and investigations above explained, there is no bug here, but a confusion between traversing the underlying data node and the form tree. If the form and its fields define the groups strategy, then the |
Symfony version(s) affected: At least 4.2.2 - 4.2.3
Description
Given the following data structure (noise like getter/setters, id properties, and some Doctrine annotations have been stripped in this paste):
We end up with some unexpected behaviour inside the
EntityB::validateRequiredFields
method, which is called beforeEntityBForm
'svalidation_groups
are resolved. I wasn't expecting the callback validation to be run before the Form has determined which validation groups are important, which led in my case to some unexpected behaviour and could introduce bugs.I was digging through some test codes which were testing for the correct validation groups, but not for an integration that makes sure they're called in the correct order, with the correct groups.
Am I missing something here or is this a bug?
How to reproduce
Reproducer: https://github.com/keichinger/symfony-validation-repro
Steps:
git clone
,composer install
, local webserver configs if necessary, etc.).env
to a.env.local
and update the DB credentialsphp bin/console doctrine:schema:update --dump-sql --force
, as I didn't create a migration/
an unstyled form (classEntityAForm
) is renderedvalidation_groups
callback inside the forms and the@Assert/Callback
validation callbacks inside the entitiesIt should look like this:

The text was updated successfully, but these errors were encountered: