gpt4 book ai didi

php - Symfony Doctrine 多对零关系

转载 作者:行者123 更新时间:2023-11-29 18:32:51 27 4
gpt4 key购买 nike

我对 Symfony 和 Doctrine 相当陌生,我不确定这是否可以完成。我可以在平面 php 中做到这一点,但似乎无法找到在 Symfony/Doctrine 中做到这一点的方法。我已经解决了很多 Stack Overflow 问题并搜索了 Google,但没有任何乐趣。

我正在开发一个项目,该项目保存有关人员的基本信息,例如姓名和头衔等。它还保存有关其雇主/组织的信息。它有两个实体/表。第一个称为 CrmPerson(用于存储有关人员的信息)。该表有一个名为 personid 的主键和一个名为 orgid 的外键。第二个表 CrmOrg 用于存储有关其组织的数据。该表有一个名为orgid 的主键,没有外键。

许多人可以为一个组织工作,一个组织也可以有许多人。 IE。多对一。我已经能够构建一个单一表单,以便当您输入有关人员及其组织的信息时,当您单击“提交”时,它将将该人员信息提交到 CrmPerson 表,并将其组织信息提交到 CrmOrg 表。

但是,我有一个问题。在某些情况下,一个人可能根本不属于某个组织。多对零(我想……如果有这样的事情的话!)。当在表单中输入人员信息但未输入组织信息时,它会将该人员的信息作为新记录提交到 CrmPerson 表(如预期),但还会在 CrmOrg 表中提交一条空记录,其中任何数据中都没有数据。除了主键orgid之外的字段(如预期但不想要)。外键 orgid 也填充在链接到 CrmOrg 中新空行的 CrmPerson 表中。这可能会导致 CrmOrg 中出现数百/数千条空记录。

是否可以实现这样的情况:如果将人员信息添加到表单但没有添加公司信息,则仅向 CrmPerson 表提交一条记录,其中包括外键 orgid 的空/空值以及不添加任何内容到底到 CrmOrg 表吗?

这是我尝试执行此操作的代码(删除了与问题无关的部分):

CrmOrg.php

<?php
// src/AppBundle/Entity/CrmOrg.php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
* CrmOrg
*
* @ORM\Table(name="crm_org", indexes={@ORM\Index(name="index_org", columns=
{"orgid", "memberid"})})
* @ORM\Entity
*/
class CrmOrg
{
/**
* @var integer
*
* @ORM\Column(name="orgid", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $orgid;

/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\CrmPerson",
mappedBy="crmorg")
*/
protected $crmpersons;

/**
* CrmOrg constructor.
*/
public function __construct()
{
$this->crmpersons = new ArrayCollection();
}

CrmPerson.php

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

/**
* @var \AppBundle\Entity\CrmOrg
*
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\CrmOrg")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="orgid", referencedColumnName="orgid")
* })
*/
private $orgid;



/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\CrmOrg", inversedBy="crmpersons", cascade={"persist"})
* @ORM\JoinColumn(name="orgid", referencedColumnName="orgid", nullable=false)
*/
protected $crmorg;

PersonController.php

<?php
// src/AppBundle/Entity/PersonController.php

namespace AppBundle\Controller;

use AppBundle\Form\CrmPersonType;
use AppBundle\Entity\CrmPerson;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Doctrine\ORM\EntityManagerInterface;




class PersonController extends Controller
{

/**
* @var EntityManagerInterface
*/
private $em;

public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}

/**
* @Route("/user/person_add", name="person_add")
*/
public function personAddAction(Request $request)
{
$form = $this->createForm(CrmPersonType::class);



$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {

$em = $this->getDoctrine()->getManager();

$crmperson = $form->getData();

$em->persist($crmperson);
$em->flush();

return $this->redirectToRoute('lead');
}

return $this->render(':lead:lead.add.html.twig', [
'leadForm' => $form->createView()
]);
}

CrmPersonType

<?php
// src/AppBundle/Entity/CrmPersonType.php


namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use AppBundle\Entity\CrmPerson;
use AppBundle\Entity\CrmOrg;
use AppBundle\Form\CrmOrgType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;


class CrmPersonType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', ChoiceType::class, array(
'choices' => array(
'Mr' => 'Mr',
'Miss' => 'Miss',
'Mrs' => 'Mrs',
'Ms' => 'Ms',

),
'required' => false,
))

->add('firstName', TextType::class, array(
'required' => false,
))
->add('middleNames', TextType::class, array(
'required' => false,
))
->add('surname', TextType::class, array(
'required' => false,
))
->add('tel', TextType::class, array(
'required' => false,
))
->add('mob', TextType::class, array(
'required' => false,
))
->add('email', TextType::class, array(
'required' => false,
))
->add('jobTitle', TextType::class, array(
'required' => false,
))

->add('crmorg', CrmOrgType::class)
->add('submit', SubmitType::class, [
'label' => 'Save',
'attr' => [
'class' => 'btn btn-success'
]
])
;
}

CrmOrgType

<?php
// src/AppBundle/Entity/CrmPersonType.php

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

class CrmOrgType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('companyName', TextType::class, array(
'required' => false,
))
->add('companyWebsite', TextType::class, array(
'required' => false,
))
->add('industry', TextType::class, array(
'required' => false,
))


;
}

最佳答案

$orgid@JoinColumn注解中,添加nullable=true参数:

@ORM\JoinColumn(name="orgid", referencedColumnName="orgid", nullable=true)

这样,您就不必将用户与任何组织关联。

顺便说一句,如果您只有一个连接列,则无需在 @JoinColumns 内放置 @JoinColumn 注解。您只需将 @JoinColumn 注释放在 @ManyToOne 的正下方即可。

关于php - Symfony Doctrine 多对零关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45547538/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com