Symfony2:防止数据库中的重复数据库,形式为多对一 [英] Symfony2: Prevent duplicate in database with form Many to One

查看:77
本文介绍了Symfony2:防止数据库中的重复数据库,形式为多对一的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



当新学生注册时,我将父母的表单嵌入另一个表单Student包含一个学生的父母的数据。将他的父母记录在数据库中的另一个表中。那么如果一个现在的兄弟的新生需要注册,这意味着父母已经在数据库中注册了,应该防止父母再次在数据库中注册,只能升级。



我被告知这是使用数据变压器解决的,但我不知道如何使用它。如果有人可以帮助我,我会很感激。这里我留下代码:



StudentType.php

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

实体父母

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

//国家身份证件
//我们已经删除了@UniqueEntity(fields = {NID},message =...)
// so您可以将任何NID放在表单上,​​然后检查其存在是否插入。
/ **
* @var string
*
* @ ORM\Column(name =NID,type =string,length = 10)
* @ Assert\NotBlank()
* /
private $ nid;

//更多属性...

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

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

return $ this;
}

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

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

  / ** 
*创建一个新的学生实体。
*
* /
public function createAction(Request $ request)
{
$ entity = new Student();
$ form = $ this-> createCreateForm($ entity);
$ form-> handleRequest($ request);

if($ form-> isValid()){

$ responsible1 = $ em-> getRepository('BackendBundle:Parents') - > findResponsible实体 - > 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();


返回$ 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); //该数字对应于父元素的$ 
$ 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);
}

它应该可以工作。


$ b $但是我认为一个更好的解决方案是将事件监听器添加到 FormEvents :: SUBMIT 事件中。此事件允许您更改表单数据的归一化表示形式的数据。所以你需要做的就是这样:

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

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

//在这里你检查数据库,看看你是否有一个这个nid
的父项//如果一个父项存在,将当前提交的父数据替换为db中存在的父实体
}

希望这有帮助。让我知道如果我必须提供更多的细节。


I have a Parents form embedded into another form Student containing the data of the parents of a student with an association of Many to one.

When a new student registration are recorded his parents in another table in the database. Then if a new student who is brother of an existing need to register, meaning that parents are already registered in the database, should be prevented from parents to register again in the database, could only upgrade .

I'm told that this is solved using data transformers, but I do not know how to use it. If someone could help me I would appreciate it. Here I leave the code:

StudentType.php

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

Entity Parents

     /**
 * @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;
}

Entity Student

 //...
 /**
 * @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(),
    ));
}

With the above code attempts to solve the problem but it gives me error to persist data to the database and will not let me add to the database, but if you use the following code to test the new student creates and assigns parents corresponding not create them again (assuming you were already created earlier).

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

I do not know if what I'm doing is right.I read something to use Data Transformers or event listener as PrePersist and Preupdate, but I don't know how to use this.

Thanks in advance for your answers.

解决方案

Instead of

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

you can write

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

And it should work.


But I think a better solution will be to add an event listener to the FormEvents::SUBMIT event. This event allows you to change data from the normalized representation of the form data. So all you need to do is something like this:

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
   }

Hope this helps. Let me know if I have to give more details.

这篇关于Symfony2:防止数据库中的重复数据库,形式为多对一的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆