Symfony2和Doctrine2:使用两个实体填充表单(一个复杂的场景)

Mil*_*loš 9 php entity symfony-forms symfony doctrine-orm

我有5个实体:

  • 用户,
  • 人,
  • UserAffiliation,
  • PersonAffiliation和
  • 联系

这是架构:

在此输入图像描述

一些细节:

  • WebUser是在网站上注册的人员.对于每个Webuser,都有一个人员ID.

  • 一个人可以是网络用户,作者等.

  • 每个WebUser都有0个或更多个从属关系.这些隶属关系是由这个WebUser创建的,并在能干的UserAffiliations中链接.

  • Web用户还可以将他创建的从属关系链接到一个人(如果该人是作者),并且将填充实体人员关系.

我现在正试图让webuser为作者(人)分配一个联盟.为此,我有:

  • 在实体人员中

    @ORM\OneToMany(targetEntity="PersonAffiliation", mappedBy="person", cascade={"persist", "remove"})
    
    protected $affiliations;
    
    Run Code Online (Sandbox Code Playgroud)
  • 在PersonAffiliation中

    @ORM\ManyToOne(targetEntity="Person", inversedBy="affiliations")
    @ORM\JoinColumn(name="person_id", referencedColumnName="id")
    
    protected $person;
    
    @ORM\ManyToOne(targetEntity="Affiliation", inversedBy="person_affiliations")
    @ORM\JoinColumn(name="affiliation_id", referencedColumnName="id")
    
    protected $affiliation;
    
    Run Code Online (Sandbox Code Playgroud)
  • 在实体用户中:

    @ORM\OneToMany(targetEntity="UserAffiliation", mappedBy="user")
    
    protected $affiliations;
    
    
    @ORM\ManyToOne(targetEntity="Person")
    @ORM\JoinColumn(name="person_id", referencedColumnName="id")
    
    protected $person;
    
    Run Code Online (Sandbox Code Playgroud)
  • 在Entity UserAffiliation中

    @ORM\ManyToOne(targetEntity="User", inversedBy="affiliations")
    @ORM\JoinColumn(name="user_id", referencedColumnName="id")
    
    protected $user;
    
    
    @ORM\ManyToOne(targetEntity="Affiliation", inversedBy="user_affiliations")
    @ORM\JoinColumn(name="affiliation_id", referencedColumnName="id")
    
     protected $affiliation;
    
    Run Code Online (Sandbox Code Playgroud)

在表单中,我正在做下一个:

$builder->add('affiliations', 'entity', array(
            'class' => 'SciForumVersion2Bundle:PersonAffiliation',
            'query_builder' => function($em) use ($person){
            return $em->createQueryBuilder('pa')->where('pa.person_id = :id')->setParameter('id', $person->getId());
        },
            'property'    => 'affiliation',
            'multiple' => true,
            'expanded' => true,
        ));
Run Code Online (Sandbox Code Playgroud)

但是这一切都没有按照我的意愿运作.

说明:当我尝试添加新的联盟时,它仅为WebUser添加,我无法通过表单将其链接到作者(Person).

你对如何解决这个问题有所了解,或者可能是一个很好的教程吗?

Lig*_*art 2

这应该在 Entity1Controller.php 中处理:

public function createAction(Request $request)
{
  $securityContext = $this->get('security.context');
  $em = $this->getDoctrine()->getManager();
  $form = $this->createForm(new Entity1Type()
     ,null,array('attr' => array('securitycontext' => $securityContext)));
  $form->bind($request);

  if ($form->isValid()){
    $data = $form->getData();
    $entity1id = $data->getId();
    $entity2id = $data->getEntity2Id();
    $entity1medicaid=$data->getMedicaidID();
    $entity1=$em->getRepostiory('projectBundle:Entity1')->findOneById($entity1id);
    $entity2=$em->getRepository('projectprojectBundle:Entity2')->findOneById($entity2id);
    if (null === $entity1){
      $entity1=new entity1();
      $entity1->setEntity2id($entity2id);
      $entity1->setID($entity1id);
    }
    if (null === $entity2){
      $entity2=new entity2();
      $entity2->setID($entity2id);
    }
    $em->persist($entity1);
    $em->persist($entity2);
    $em->flush();
    return $this->redirect($this->generateUrl('entity1', array()));
  }

  return $this->render('Bundle:entity1:new.html.twig', array(
      'form'   => $form->createView()
     ,'attr' => array('securitycontext' => $securityContext
     )
  )
  );
}
Run Code Online (Sandbox Code Playgroud)

您可能还必须在关联映射中设置级联持久性。实体1.yml:

project\projectBundle\Entity\Entity1:
    type: entity
    table: entity1
    repositoryClass: project\projectBundle\Entity\Entity1Repository
    fields:
        id:
            type: bigint
            id: true
            generator:
                strategy: AUTO
        property:
            type: string
            length: 255
            unique: true
    manyToMany:
        entity2:
            targetEntity: entity2
            mappedBy: entity1
            cascade: ["persist"]
Run Code Online (Sandbox Code Playgroud)

理论上,symfony 会在后台创建实体2,使得第二个 if null 子句变得不必要,但这总是让我烦恼,所以我更喜欢明确地这样做。