小编典典

Symfony2:以多对一形式防止数据库重复

ajax

我将“父母”表单嵌入到另一个“学生”表单中,该表单包含一个学生的父母的数据,并且具有“多对一”关联。

当一个新的学生注册被记录时,他的父母在数据库的另一个表中。然后,如果作为现有兄弟的新学生需要注册,这意味着父母已经在数据库中注册,则应阻止父母再次在数据库中注册,只能升级。

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

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(),
    ));
}

上面的代码试图解决问题,但是它给我错误,无法将数据持久保存到数据库中,并且不允许我添加到数据库中,但是如果您使用以下代码测试新学生创建并分配相应的父母则不创建它们再次(假设您已经创建过)。

    $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());

我不知道我在做什么是否正确。我读了一些资料,将数据转换器或事件侦听器用作PrePersist和Preupdate,但我不知道该如何使用。

预先感谢您的回答。


阅读 263

收藏
2020-07-26

共1个答案

小编典典

代替

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
   }

希望这可以帮助。让我知道是否需要提供更多详细信息。

2020-07-26