Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Assert\Valid not working as expected with Embedded Forms and validation groups #9650

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

Closed
guillaumesmo opened this issue Nov 28, 2013 · 38 comments

Comments

@guillaumesmo
Copy link
Contributor

The Assert\Valid is not taken into account and the form is just considered valid, even if the constraints are not met. The issue can be reproduced by taking the example over here :
http://symfony.com/doc/current/book/forms.html#embedding-a-single-object

  • Add any constraint to Entity\Category with: groups={"validationgroup"}
  • Change @Assert\Type(...) in Entity\Task to @Assert\Valid
  • Add 'validation_groups' => array('validationgroup') to Form\Type\CategoryType in $resolver->setDefaults
  • Remove 'cascade_validation' => true, from Form/Type/TaskType. As we use Assert\Valid, this should not be necessary, or am I wrong?
  • Create a controller:
class TestController extends Controller
{
    public function indexAction()
    {
        $form = $this->createForm(new TaskType(), new Task());
        $form->add('save', 'submit');

        $form->handleRequest($this->getRequest());

        if($form->isValid()){
            echo '<p>the form is valid...</p>';
        }

        return $this->render('AcmeDemoBundle:Test:taskform.html.twig', array(
            'form' => $form->createView()
        ));
    }
}
  • and twig template :
<h3>Add task</h3>
{{ form(form) }}

I can provide you this bundle, zipped, if you want. I have also found that (by placing a debug closure in validation_groups) the validation_groups is read by the validator but it doesn't seem to be used.

Tested with version 2.3.7

capture

@Koc
Copy link
Contributor

Koc commented Nov 30, 2013

Seems like duplicate of #3622

@guillaumesmo
Copy link
Contributor Author

Not really, the issue #3622 is about using groups inside the Valid constraint, in my case I don't use groups in the Valid constraint because they are not even allowed. I use groups in other constraints defined in the entities associated with a valid-constrained field.

@peterrehm
Copy link
Contributor

@guillaumesmo Can you provide your bundle on github?

@guillaumesmo
Copy link
Contributor Author

Here you go : https://github.com/guillaumesmo/src

You have to bypass the HTML5 constraint to test the validation or use a constraint which will not be validated by HTML5

@peterrehm
Copy link
Contributor

@guillaumesmo It seems like Assert\Valid() is not cascading the validation group. If you add the validation_groups setting you have in CategoryType also into TaskType it works as expected. I guess I had the same issue once and I was just using cascade_validation instead of Assert\Valid. Actually therefore I have never used Assert\Valid().

However it seems like an issue with the Valid constraint. I am unsure if this is wanted behavior. It is also quite strange that at least the validation_groups option on the child form is called. @bschussek can you say quickly anything regarding this behavior? In any case it seems that cascade_validation behaves not exactly the same as Assert/Valid().

@guillaumesmo
Copy link
Contributor Author

In my opinion it's quite clear from the documentation that the purpose of Assert/valid() is to validate the underlying entity.

The only reason I can imagine this being "expected behavior" is if the validation group could only be set from the main form. But in that case we shouldn't be allowed to set validation groups like we did in the embedded form type.

@peterrehm
Copy link
Contributor

Meanwhile you can use cascade_validation. I was debugging a bit more right now, but could not yet find the root cause. I would like to await some feedback from @bschussek and then we can see further.

@li0n12
Copy link

li0n12 commented Dec 14, 2013

Validator should stop any further validation whe it meets Assert/Valid.
Assert/Valid is not accepting any groups so it should be applied for any group.

but currently it ignores Assert/Valid when validation is done for group validationgroup

@guillaumesmo
Copy link
Contributor Author

No I'm sorry but your first sentence is wrong. Citation from http://symfony.com/doc/current/reference/constraints/Valid.html: "This constraint is used to enable validation on objects"

It is indeed not accepting any groups but as I said before I didn't apply any group to the Valid constraint in my example. And your third phrase is a good summary of the issue.

@peterrehm
Copy link
Contributor

@li0n12 Thanks for the work, but unfortunately you can close your PR, I have the test case already on my machine, unfortunately I could not get into discussion with @bschussek later today, but I hope to be able to get a hold of him next week.

Once I have more information I will get back to this issue.

@wouterj
Copy link
Member

wouterj commented Jul 28, 2014

This doesn't seem to be an easy pick issue, can someone please remove the label?

@webmozart can you give your opinion on this one?

@peterrehm
Copy link
Contributor

I have just checked it again with 2.5.x-dev and it is also still not working with the 2.5 validator api.
The issue can be reproduced with my branch https://github.com/peterrehm/symfony-standard/tree/valid-constraint. @webmozart Do you still have that one on your Todo list? :)

@jakzal jakzal removed the Easy Pick label Jul 29, 2014
@ioleo
Copy link

ioleo commented Aug 29, 2014

@peterrehm In my case, when I renamed @Asset\Valid() to @Assert\Valid it worked. You may want to upgrade your demo and test it.

@peterrehm
Copy link
Contributor

@loostro Just retried it. If I remove the cascade_validation option on TaskType the Assert\Valid does not have any impact. You can try it out with my branch https://github.com/peterrehm/symfony-standard/tree/valid-constraint

@jakzal
Copy link
Contributor

jakzal commented Sep 11, 2014

@peterrehm @guillaumesmo indeed your efforts to reproduce the issue confirm this is a bug. Thanks!

@jakzal
Copy link
Contributor

jakzal commented Sep 11, 2014

I did a bit more digging. Validation on a child form is not triggered if the validation groups are only defined on a child form. Defining validation groups on the parent form, triggers child validation.

@peterrehm
Copy link
Contributor

@jakzal Have you found out why Assert\Valid() is behaving other then cascase_validation? Because iirc it should behave exactly the same.

@jakzal
Copy link
Contributor

jakzal commented Sep 12, 2014

@peterrehm not yet, it was too late yesterday ;)

@jakzal jakzal added the Form label Sep 12, 2014
@jakzal
Copy link
Contributor

jakzal commented Sep 12, 2014

// The Valid constraint, on the other hand, is always executed and propagates
// the group to the cascaded object. The propagated group depends on
//
// * Whether a group sequence is currently being executed. Then the default
// group is propagated.
//
// * Otherwise the validated group is propagated.
:

// The Valid constraint, on the other hand, is always executed and propagates
// the group to the cascaded object. The propagated group depends on
//
//  * Whether a group sequence is currently being executed. Then the default
//    group is propagated.
//
//  * Otherwise the validated group is propagated.

The way I read it in relation to forms is that if your parent form doesn't have any validation groups, the default one is propagated down.

@peterrehm
Copy link
Contributor

I would read it the same way. This means it is actually not really a bug just a strange behaviour since
Assert\Valid() works different to cascade_validation.

If you add (in my reproducible branch) the validation group to the main form and not the sub form it works as expected but it is strange.

I think if cascade_validation uses the validation_groups setting of the child form the Validate() constraint should have exactly the same behavior. Especially since we educate that both options are working the same way and are replaceable:

http://symfony.com/doc/current/reference/forms/types/form.html#cascade-validation

@jakzal
Copy link
Contributor

jakzal commented Sep 13, 2014

ping @webmozart :)

@f3rch0
Copy link

f3rch0 commented Oct 16, 2014

I managed to make it work by passing the cascade_validation and validation_groups as an options to collection field. It works even if i turn off Valid assert.

@peterrehm
Copy link
Contributor

Be aware with #12237 the cacade_validation option might get deprecated.

@webmozart
Copy link
Contributor

@peterrehm I just looked at your demo bundle. You did not set the "validationgroup" on TaskType. If you set the group there and remove the "cascade_validation" settings, then the Length constraint in Category should be validated.

@webmozart
Copy link
Contributor

@peterrehm I checked out the demo bundle now and tested it. The validation works for me without doing any changes. Additionally, if removing "cascade_validation" and moving the "validation_groups" option from CategoryType to TaskType, validation works too.

Maybe the crucial point is that the "validation_groups" setting is only respected on the root form (unless "cascade_validation" is used), because that's the form which triggers the validation process.

@peterrehm
Copy link
Contributor

Yes this is the crucial point. I think it makes no sense to ignore the child validation_groups settings. I think you need to have your validation group logic separated to each form. You don't want to duplicate the logic.

@bkosborne
Copy link

Maybe the crucial point is that the "validation_groups" setting is only respected on the root form (unless "cascade_validation" is used), because that's the form which triggers the validation process.

I think this needs to be in the documentation for Forms. If I'm reading this correctly, then setting validation_groups on embedded forms have no effect, and only the validation_groups on parent form's matter?

It seems counter-intuitive to me that I'd have to set a validation group on the parent form when it only applies to the underlying object for an embedded form.

@alanhartless
Copy link

I'm having this same issue and nothing I'm trying short of manually handling the validation/error throwing is working.

I have an entity, a form type for that entity, and using validation_groups.

The entity has an array property that is associated with second form type embedded in the parent/entity's form type.

The embedded form type have constraints defined in it's properties' options.

I've tried cascade_validation in the parent form type for the array property. I've tried defining a Valid() constraint on the property in the entity's loadValidatorMetadata() class. But nothing seems to trigger the embedded form type constraints.

Does Valid() with validation_groups only work with objects/entities and not property/nested arrays?

If I remove the validation group, all the constraints are appropriately honored (but in this case, I need to use groups).

@cesarluna
Copy link

cesarluna commented Apr 27, 2017

Validation messages are displayed at the parent form level. I'd like those messages to be displayed at formChild.field level. I'm using Symfony 3.2 version.

@peterrehm
Copy link
Contributor

@cesarluna Please write your comments in english here

@javiereguiluz
Copy link
Member

@cesarluna I've translated your message into English because, as @peterrehm said, we only accept English comments in this repository. Please, write your future comments in English. Thanks!

@cesarluna
Copy link

Thanks for the translation

@Kwadz
Copy link

Kwadz commented Mar 19, 2018

So, since cascade_validation has been removed, should we understand that we are no longer able to set validation_group on embedded forms?

@peterrehm
Copy link
Contributor

Yes the option is removed. See #17302 (comment). Since the validation groups are still propagated to the childs you are still very flexible.

@Kwadz
Copy link

Kwadz commented Mar 19, 2018

Yes but that means we are no longer able to set different validation groups for each item of a collection, right?
Or by "flexible" you meant we can manage to do it?

@peterrehm
Copy link
Contributor

@Kwadz All should be possible, see my docs PR symfony/symfony-docs#4348

@Kwadz
Copy link

Kwadz commented Mar 20, 2018

@peterrehm, thanks but in this link there is nothing related to set different validation groups for each item of a collection. I think you didn't understand what I am talking about.

Are we still able to to set different validation groups for each item of a collection in Symfony 3?

@peterrehm
Copy link
Contributor

@Kwadz Read this carefully http://symfony.com/doc/current/validation/groups.html. You can apply all constraints on the main entity depending on your design. This is what I do in my apps. Therefore it is required that you understand Default, Classname,... Groups.

Also have a look at #11880

Also this might give you an option with a custom dynamic constraint which I use in one of my apps #16984

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

No branches or pull requests