我安装了Symfony3,我正在尝试使用@Assert \ Valid注释验证普通表单中的formchild(实体子/非映射字段)。我做不到,所以我尝试了手册中的例子: http://symfony.com/doc/current/reference/constraints/Valid.html
这个例子,在Symfony 3中,不起作用(至少对我而言)。 这是使用@Assert \ Valid的地方。在这种情况下,Symfony如何知道(例如来自手册)来验证地址实体而不是任何其他实体?
/**
* @Assert\Valid
*/
protected $address;
是否有人试图测试手册中的示例,看看它是否有效?
有人可以提供手册中的工作示例吗?我不知道我做错了什么..
这是我的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(),
));
}
}
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);
}
}
作者实体:
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;
}
}
地址实体:
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;
}
}
这就是我现在所得到的:
Firstname
This value should not be blank.
Lastname
This value should not be blank.
Street
Zipcode
所以:主要实体已经过验证,但是继承的(街道/邮政编码)被“忽略”了..
如何验证(使用此方法,而不是创建自定义验证)子实体?
由于
答案 0 :(得分:4)
street
中的zipcode
和AuthorRegistrationType
字段与您的Address
实体无关。你这样做的原因是什么?我会为您的Address
实体创建一个单独的表单类型:
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)
;
}
}
然后您可以将其嵌入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);
}
}
答案 1 :(得分:0)
在您的实体Author
中,您有一个属性address
,这是另一个实体Address
。在我看来,这被称为嵌入式实体,而不是继承。但是,我不是母语为英语的人,所以我可以保证。
问题出在您的实体Author
中:
/**
* @Assert\Valid
*/
protected $address;
这将验证字段本身,但不验证实体street
中的字段zipCode
和Address
。要实现这一点,您应该告诉验证遍历实体Address
并在那里查找验证:
/**
* @Assert\Valid(
* traverse = true
* )
*/
protected $address;
这应该可以胜任。
编辑:
在您的示例中,我无法立即看到这两个实体之间的关系。现在我看到Author
只能有一个Address
。这意味着上面建议的代码不会为您完成工作。只有在Author
有一个字段address
是一个集合的情况下才有必要,即一个作者可以有多个地址。
答案 2 :(得分:0)
xabbuh是对的:
我在控制器中添加了以下内容:
$address = new Address();
$author->setAddress($address);
前
$form = $this->createForm(AuthorRegistrationType::class, $author, array(
'required' => false
));
在AddressType:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'WebsiteBundle\Entity\Address'
));
}
它有效!