我在OneToMany
和Project
之间有一个Application
关系,我想确保2 Application
在Project
内的名称不能相同}。
我尝试按照应有的方式配置我的实体,表单类型和控制器,但我收到了重复条目的Integrity约束违规,所以我认为验证过程会被忽略。
有人能告诉我我错过了什么吗?
我的Application
实体是这样的:
namespace App\MainBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use JsonSerializable;
/**
* @ORM\Entity
* @ORM\Table(name="application", uniqueConstraints={@ORM\UniqueConstraint(name="IDX_Unique", columns={"name", "project_id"})})
* @UniqueEntity(
* fields={"name", "project"},
* message="Name already used in this project.",
* groups="application"
* )
*/
class Application implements JsonSerializable {
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string")
* @Assert\NotBlank(
* message = "Name cannot be empty."
* )
* @Assert\Length(
* min = "3",
* max = "50",
* minMessage = "Name is too short. It should have {{ limit }} characters or more.",
* maxMessage = "Name is too long. It should have {{ limit }} characters or less."
* )
*/
protected $name;
// other properties ...
/**
* @ORM\ManyToOne(targetEntity="Project", inversedBy="applications")
* @ORM\JoinColumn(name="project_id", referencedColumnName="id")
*/
protected $project;
// constructor, methods, getters, setters
}
我的ApplicationType
课程如下:
namespace App\MainBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class ApplicationType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('name', 'text', array(
'icon' => 'pencil'
));
$builder->add('description', 'textarea', array(
'required' => false,
'icon' => 'info'
));
$builder->add('url', 'url', array(
'required' => false,
'icon' => 'link'
));
}
public function getName() {
return 'application';
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => 'App\MainBundle\Entity\Application',
'validation_group' => array('application'),
'cascade_validation' => true
));
}
}
在我的Controller
中,操作如下所示:
/**
* @Route("/project/{id}/application/add",
* name="app_add_application_ajax",
* requirements={"_method" = "post"},
* options={"expose" = true }
* )
* @Secure(roles="ROLE_SUPER_ADMIN")
* @ParamConverter("project", class="AppMainBundle:Project")
*/
public function addApplicationAction(Project $project, Request $request) {
$ajaxResponse = array();
$em = $this->getDoctrine()->getManager();
if ($request->getMethod() == 'POST' && $request->isXmlHttpRequest()) {
$formApp = new Application();
$formApp->setProject($project);
$form = $this->createForm(new ApplicationType(), $formApp);
$form->handleRequest($request);
if ($form->isValid()) {
$application = $form->getData();
$em->persist($application);
$em->flush();
// build ajax response ...
} else {
$ajaxResponse['error'] = $this->getErrorsAsString();
}
}
$response = new Response(json_encode($ajaxResponse));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
答案 0 :(得分:1)
您的问题是您在表单类型中配置了validation_group
选项,而Symfony使用的选项是validation_groups
。您没有收到有关未知选项的错误,因为您在表单类型的默认选项中设置了此选项,因此您将选项标记为已定义(但它是一个单独的选项)。
因此验证器使用默认组运行,默认组将验证不同的约束(name属性长度的约束在默认组中)。
请注意,您还有第二个问题,一旦运行约束就会出现 您的验证约束与您拥有的数据库约束不匹配。您要求验证器具有唯一的名称和唯一的项目,而不是唯一的元组(名称,项目)。所以你会拒绝太多东西(这个名称将在全球范围内被验证为唯一,而不是每个项目)。 这是因为您使用2个单独的UniqueEntity约束而不是约束,要求多个字段的元组是唯一的。