当前位置: 首页 > 面试题库 >

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

蒙墨竹
2023-03-14
问题内容

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

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

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

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.html" target="_blank">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,但我不知道该如何使用。

预先感谢您的回答。


问题答案:

代替

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
   }

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



 类似资料:
  • 问题内容: 每次我通过贝宝付款时,我的信息都会在数据库中捕获,但我想防止重复。那么我该如何解决呢?还是应该检查电子邮件重复项? 编辑 据我所知,pinnaclecart将uid设置为primary。所以将它设置为唯一不是“危险”吗? 问题答案: 名字和姓氏都很好,但是除了唯一之外,其他一切都没有。我认识几个与我同名的人,因此我猜想在这两列上建立唯一索引只会令人沮丧,而无济于事。但是,使我与众不同的

  • 问题内容: 我想防止使用vb.net和MySQL作为数据库的清单表单中出现重复条目​​,这是我的代码: 结束子 我在搜索答案时发现了这个问题,但是当我尝试运行它时,它没有读取插入命令,而是即使没有相同的人员ID也会直接转到msbox“人员ID已经存在”。 有人可以检查为什么不阅读插入内容, 我的数据库表值: pcode =主键 lname =长文本 fname =长文本 办公室=长文本 名称=长文

  • 问题内容: 我有一个表,用于存储有关某些事件重复发生的值,例如,与发生在星期一,星期三和星期五的事件,以及与发生在星期一和星期三的事件。所以我的桌子是这样的: 我的问题是有时(并非总是)我的脚本在数据库中插入重复的值,因此我的表的事件1和2的重复发生率是两倍,如下面的表所示: 如果我在列中添加约束,则事件1仅具有星期一值,但我希望该值具有其余值,例如星期三和星期五。如何添加约束来解决此问题? 问题

  • 问题内容: 我想知道如何防止在数据库表中使用两个相同的标签。有人说我在表中使用两个私钥。但是,W3Schools-网站表示这是不可能的。 问题答案: 我已经更新了NORMA模型,使其与您的图表更加匹配。我可以看到您在哪里犯了一些错误,但是其中一些错误可能是由于我的早期模型造成的。 我已更新此模型以防止重复标签。以前真的没关系。但是,既然您想要它,这里就是(对于Postgres): 请注意,现在有一

  • 问题内容: 我正在工作,我有下表 现在我想防止插入,如果我有一个数据,尽管ID不同但存在数据 请指导我如何编写此触发器。 问题答案: 像这样的东西: 那只是为了插入,您可能也想考虑更新。 更新 一种更简单的方法是在表上创建唯一约束,这也将强制它进行更新并消除对触发器的需求。做就是了: 然后你就可以做生意。

  • 我对spring boot data jpa有点陌生,据我所知@entity用于表示应用程序中的数据库表,对于这个项目来说,我使用和作为内存数据库。 到目前为止我有这个。 在resources/data.sql内部 在执行应用程序时,我得到了这个错误 为什么@Entity试图重新创建一个应该只表示的表,有没有一种方法可以禁用它?