Reputation: 105
I installed Symfony3 and I'm trying to validate a formchild (entity child/not mapped fields) inside a normal form, with @Assert\Valid annotation. I couldn't do it so I tried the example from the Manual: http://symfony.com/doc/current/reference/constraints/Valid.html
This example, in Symfony 3, doesn't work (at least for me). This is where @Assert\Valid is used. How does Symfony knows in this case (example from manual) to valid the Address Entity and not any other Entity?
/**
* @Assert\Valid
*/
protected $address;
Has someone tried to test the example from the manual to see if it works?
Can someone please provide the working example from the manual? I don't know what I'm doing wrong..
This is my TestingController.php:
namespace WebsiteBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use WebsiteBundle\Entity\Author;
use WebsiteBundle\Form\Type\AuthorRegistrationType;
class TestingController extends Controller
{
public function registerAccountAction(Request $request)
{
$author = new Author();
$form = $this->createForm(AuthorRegistrationType::class, $author, array(
'required' => false
));
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
echo "It works";
}
return $this->render('TemplatesBundle:Default:testing_registration.html.twig', array(
'form' => $form->createView(),
));
}
}
The AuthorRegistrationType.php:
namespace WebsiteBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class AuthorRegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add("firstname")
->add("lastname")
->add("zipcode", TextType::class, array('mapped' => false))
->add("street", TextType::class, array('mapped' => false))
->add('save', SubmitType::class);
}
}
Author Entity:
namespace WebsiteBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Author
{
/**
* @Assert\NotBlank
* @Assert\Length(min = 4)
*/
protected $firstname;
/**
* @Assert\NotBlank
*/
protected $lastname;
/**
* @Assert\Valid
*/
protected $address;
/**
* @return mixed
*/
public function getFirstname()
{
return $this->firstname;
}
/**
* @param mixed $firstname
*/
public function setFirstname($firstname)
{
$this->firstname = $firstname;
}
/**
* @return mixed
*/
public function getLastname()
{
return $this->lastname;
}
/**
* @param mixed $lastname
*/
public function setLastname($lastname)
{
$this->lastname = $lastname;
}
/**
* @return mixed
*/
public function getAddress()
{
return $this->address;
}
/**
* @param mixed $address
*/
public function setAddress(Address $address)
{
$this->address = $address;
}
}
Address Entity:
namespace WebsiteBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Address
{
/**
* @Assert\NotBlank()
*/
protected $street;
/**
* @Assert\NotBlank
* @Assert\Length(max = 5)
*/
protected $zipCode;
/**
* @return mixed
*/
public function getStreet()
{
return $this->street;
}
/**
* @param mixed $street
*/
public function setStreet($street)
{
$this->street = $street;
}
/**
* @return mixed
*/
public function getZipCode()
{
return $this->zipCode;
}
/**
* @param mixed $zipCode
*/
public function setZipCode($zipCode)
{
$this->zipCode = $zipCode;
}
}
This is what I get now:
Firstname
This value should not be blank.
Lastname
This value should not be blank.
Street
Zipcode
So: the main Entity is validated, but the inherited one (Street/Zipcode) is "ignored"..
How can I validate (with this metod, not creating Custom Validation) the child entity?
Thanks
Upvotes: 2
Views: 3319
Reputation: 12012
In your entity Author
you have an attribute address
, which is another entity Address
. In my opinion this is called embedded entity, not inherited. However I'm not a native English speaker, so I cannot guarantee.
The issue is in your entity Author
:
/**
* @Assert\Valid
*/
protected $address;
This will validate the field itself, but not the fields street
and zipCode
from the entity Address
. To achieve that, you should tell the validation to traverse to the entity Address
and look up for the validations in there:
/**
* @Assert\Valid(
* traverse = true
* )
*/
protected $address;
This should do the job.
EDIT:
I couldn't see the relation between these two entities immediately in your examples. Now I see that Author
can have only one Address
. That means the above suggested code won't do the work for you. It is necessary only if you have a relation where an Author
has a field address
which is a collection, i.e one author can have many addresses.
Upvotes: 0
Reputation: 105
xabbuh is right:
I added in the controller the following:
$address = new Address();
$author->setAddress($address);
before
$form = $this->createForm(AuthorRegistrationType::class, $author, array(
'required' => false
));
And in AddressType:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'WebsiteBundle\Entity\Address'
));
}
And it works!
Upvotes: 1
Reputation: 5881
The street
and zipcode
fields in your AuthorRegistrationType
are not related to your Address
entity. What is the reason you did it this way? I would create a separate form type for your Address
entity:
namespace WebsiteBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class AddressType extends AbstractType
{
protected function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('street', TextType::class)
->add('zipCode', TextType::class)
;
}
}
Then you can embed this in your AuthorRegistrationType
:
namespace WebsiteBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
class AuthorRegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add("firstname")
->add("lastname")
->add("address", AddressType::class)
->add('save', SubmitType::class);
}
}
Upvotes: 4