php - Symfony2 : Prevent duplicate in database with form Many to One

标签 php ajax forms symfony doctrine-orm

我有一个 Parents 表单嵌入到另一个表单 Student 中,其中包含具有多对一关联的学生家长的数据。

当一个新学生注册时,他的 parent 被记录在数据库的另一个表中。那么如果一个现有的兄弟的新学生需要注册,也就是说 parent 已经在数据库中注册,应该阻止 parent 再次在数据库中注册,只能升级。

有人告诉我这是使用数据转换器解决的,但我不知道如何使用它。如果有人可以帮助我,我将不胜感激。这里我留下代码:

StudentType.php

  //...
  ->add('responsible1', new ParentsType(),array('label' => 'Mother'))
  ->add('responsible2', new ParentsType(),array('label'=> 'Father'))

实体父级

     /**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

//National identity document
//we have removed "@UniqueEntity(fields={"NID"}, message="...")" 
//so you can put any NID on the form and then check its existence to insert or not.
/**
 * @var string
 *
 * @ORM\Column(name="NID", type="string", length=10)
 * @Assert\NotBlank()
 */
private $nid;

 //more properties...

 /**
 * @ORM\OneToMany(targetEntity="Student", mappedBy="$responsible1")
 * @ORM\OneToMany(targetEntity="Student", mappedBy="$responsible2")
 */
 private $students;

 //...
 public function addStudent(\Cole\BackendBundle\Entity\Student $students)
{
    $this->students[] = $students;

    return $this;
}

public function removeStudent(\Cole\BackendBundle\Entity\Student $students)
{
    $this->students->removeElement($students);
}

public function getStudents()
{
    return $this->students;
}

实体学生

 //...
 /**
 * @ORM\ManyToOne(targetEntity="Parents", inversedBy="students", cascade={"persist"})
 */
 private $responsible1;

/**
 * @ORM\ManyToOne(targetEntity="Parents", inversedBy="students", cascade={"persist"})
 */
 private $responsible2;

 //...

public function setResponsible1($responsible1)
{
    $this->responsible1 = $responsible1;

    return $this;
}


public function getResponsible1()
{
    return $this->responsible1;
}


public function setResponsible2($responsible2)
{
    $this->responsible2 = $responsible2;

    return $this;
}

public function getResponsible2()
{
    return $this->responsible2;
}

ParentsRepository.php

 class ParentsRepository extends EntityRepository
 {
   public function findResponsible($nid)
   {
    return $this->getEntityManager()->createQuery(
        'SELECT p FROM BackendBundle:Parents p WHERE p.nid=:nid')
    ->setParameter('nid',$nid)
    ->setMaxResults(1)
    ->getOneOrNullResult();
   }
 }

StudentController.php

/**
 * Creates a new Student entity.
 *
 */
public function createAction(Request $request)
{
    $entity = new Student();
    $form = $this->createCreateForm($entity);
    $form->handleRequest($request);

    if ($form->isValid()) {

    $responsible1 = $em->getRepository('BackendBundle:Parents')->findResponsible($entity->getResponsible1()->getNid());
    $responsible2 = $em->getRepository('BackendBundle:Parents')->findResponsible($entity->getResponsible2()->getNid());

   if($responsible1){
         $entity->setResponsible1($responsible1->getId()); 
   }
   if($responsible2){
         $entity->setResponsible2($responsible2->getId()); 
   }
   $entity->getResponsible1()->setUsername($entity->getResponsible1()->getNid());
   $entity->getResponsible2()->setUsername($entity->getResponsible2()->getNid());

   $entity->getResponsible1()->setPassword($entity->getResponsible1()->getNid());
   $entity->getResponsible2()->setPassword($entity->getResponsible2()->getNid());


        $em = $this->getDoctrine()->getManager();
        $em->persist($entity);
        $em->flush();


        return $this->redirect($this->generateUrl('student_show', array('id' => $entity->getId())));
    }

    return $this->render('BackendBundle:Student:new.html.twig', array(
        'entity' => $entity,
        'form'   => $form->createView(),
    ));
}

用上面的代码试图解决问题但是它给我错误将数据持久化到数据库并且不会让我添加到数据库,但是如果你使用下面的代码来测试新学生创建并分配 parent 相应不要再次创建它们(假设您之前已经创建过)。

    $responsible1 = $em->getRepository('BackendBundle:Parents')->findResponsible(4); //The number corresponds to the id of the parent
    $responsible2 = $em->getRepository('BackendBundle:Parents')->findResponsible(5);

    $entity->setResponsible1($responsible1->getId()); 
    $entity->setResponsible2($responsible2->getId()); 

我不知道我在做什么是否正确。我读了一些关于使用 Data Transformers 或事件监听器作为 PrePersist 和 Preupdate 的东西,但我不知道如何使用它。

预先感谢您的回答。

最佳答案

代替

if($responsible1){
     $entity->setResponsible1($responsible1->getId()); 
}
if($responsible2){
     $entity->setResponsible2($responsible2->getId()); 
}
$entity->getResponsible1()->setUsername($entity->getResponsible1()->getNid());
$entity->getResponsible2()->setUsername($entity->getResponsible2()->getNid());

$entity->getResponsible1()->setPassword($entity->getResponsible1()->getNid());
$entity->getResponsible2()->setPassword($entity->getResponsible2()->getNid());

你可以写

if($responsible1){
     $entity->setResponsible1($responsible1); 
}
if($responsible2){
     $entity->setResponsible2($responsible2); 
}

它应该可以工作。


但我认为更好的解决方案是向 FormEvents::SUBMIT 事件添加一个事件监听器。此事件允许您从表单数据的规范化表示更改数据。所以你需要做的就是这样:

public function onSubmit(FormEvent $event)
{
   $student = $event->getData();

   if ($student->getResponsible1()) {
        $parentNid = $student->getResponsible1()->getNid();

        // here you check the database to see if you have a parent with this nid
        // if a parent exists, replace the current submitted parent data with the parent entity existing in your db
   }

希望这对您有所帮助。让我知道是否需要提供更多详细信息。

关于php - Symfony2 : Prevent duplicate in database with form Many to One,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34285413/

相关文章:

php - 将包含多个用户 ID 的数组与用户表连接起来并创建新数组

c# - 如何验证 ASPNET AJAX 安装

javascript - 如果选中复选框则禁用输入

php - 尝试将数据加载到 ChoiceType 表单中,但没有保存

c# - ASP.NET MVC 复杂模型更新

php - 使用查询模拟预加载

php - 如何在 Laravel 中验证日期

php - 我的网站有一个 php 标题,里面有一个 css 动画,但我不想在某些页面上出现动画

jquery - $.ajax get, mvc 3 jsonresult - 未定义结果

javascript - javascript中的内存泄漏,循环内的函数