Skip to content

More concrete explanation of validation groups #4454

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
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 32 additions & 3 deletions book/forms.rst
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@ to an array callback::

use Symfony\Component\OptionsResolver\OptionsResolverInterface;

// ...
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
Expand All @@ -536,23 +537,51 @@ This will call the static method ``determineValidationGroups()`` on the
The Form object is passed as an argument to that method (see next example).
You can also define whole logic inline by using a ``Closure``::

use Acme\AcmeBundle\Entity\Client;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

// ...
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'validation_groups' => function(FormInterface $form) {
$data = $form->getData();
if (Entity\Client::TYPE_PERSON == $data->getType()) {
if (Client::TYPE_PERSON == $data->getType()) {
return array('person');
} else {
return array('company');
}

return array('company');
},
));
}

Using the ``validation_groups`` option overrides the default validation
group which is being used. If you want to validate the default constraints
of the entity as well you have to adjust the option as follows::

use Acme\AcmeBundle\Entity\Client;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

// ...
public function setDefaultOptions(OptionsResolverInterface $resolver)
Copy link
Member

Choose a reason for hiding this comment

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

we usually add a line with // ... before such methods, to indicate that some code is "folded" (in this case, the class definition)

{
$resolver->setDefaults(array(
'validation_groups' => function(FormInterface $form) {
$data = $form->getData();
if (Client::TYPE_PERSON == $data->getType()) {
return array('Default', 'person');
}

return array('Default', 'company');
},
));
}

You can find more information about how the validation groups and the default constraints
work in the book section about :ref:`validation groups <book-validation-validation-groups>`.

.. index::
single: Forms; Validation groups based on clicked button

Expand Down
28 changes: 27 additions & 1 deletion book/validation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -816,11 +816,37 @@ With this configuration, there are three validation groups:
referenced classes that belong to no other group;

* ``User`` - equivalent to all constraints of the ``User`` object in the
``Default`` group;
``Default`` group; This is always the name of the class. The difference
between this and Default is explained below.

* ``registration`` - contains the constraints on the ``email`` and ``password``
fields only.

Constraints in the ``Default`` group of a class are the constraints that have either no
explicit group configured or that are configured to a group equal to the class name or
the string ``Default``.

.. caution::

When validating *just* the User object, there is no difference between the ``Default`` group
and the ``User`` group. But, there is a difference if ``User`` has embedded objects. For example,
imagine ``User`` has an ``address`` property that contains some ``Address`` object and that
you've added the :doc:`/reference/constraints/valid` constraint to this property so that it's
validated when you validate the ``User`` object.

If you validate ``User`` using the ``Default`` group, then any constraints on the ``Address``
class that are in the ``Default`` group *will* be used. But, if you validate ``User`` using the
``User`` validation group, then only constraints on the ``Address`` class with the ``User``
group will be validated.

In other words, the ``Default`` group and the class name group (e.g. ``User``) are identical,
except when the class is embedded in another object that's actually the one being validated.

In case you have inheritance in your data model and you validate with the class name of
the subclass in the subclass and in the baseclass all constraints in the default group
will be validated. If you use the name of the baseclass only the constraints in the base
class will be validated.

To tell the validator to use a specific group, pass one or more group names
as the third argument to the ``validate()`` method::

Expand Down