这是情况,我有一个表格,我需要一个实体字段类型。在BenefitGroup实体中,我有一个BenefitGroupCategory选项。
我的构建形式是:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('BenefitGroupCategories', 'entity', array(
'class' => 'AppBundle:BenefitGroupCategory',
'property' => 'name',
'label' => false,
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('c')
->orderBy('c.name', 'ASC');
},))
->add('benefitsubitems', 'collection', array('type' => new BenefitSubItemFormType(), 'allow_add' => true, 'label' => false,));
}
这几乎是典型的产品类别关系。一个BenefitGroup只能有一个类别,一个类别可以属于许多BenefitGroups(唯一的复杂功能,尚未实现,但这就是我需要查询构建器的原因,是所有都依赖于另一个参数(项目)所以某些类别将是默认类别(始终可用),其他类别仅适用于特定项目(请参阅下面对BenefitGroupCategory实体中项目的引用)。
你会注意到另一个领域,即福利子项,这与手头的问题无关。
据我所知,从Doctrine的角度来看,我必须设置一对多,单向连接表。
这两个实体是:
<?php
// src/AppBundle/Entity/BenefitGroup.php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="AppBundle\Entity\BenefitGroupRepository")
* @ORM\Table(name="benefit_groups")
*/
class BenefitGroup
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\ManyToOne(targetEntity="BenefitItem", cascade={"persist"}, inversedBy="BenefitGroups")
*/
protected $benefitItem;
/**
* @ORM\oneToMany(targetEntity="BenefitSubItem", mappedBy="benefitGroup")
*/
protected $BenefitSubItems;
/**
* @ORM\ManyToMany(targetEntity="BenefitGroupCategory")
* @ORM\JoinTable(name="BenefitGroup_BenefitGroupCategory", joinColumns={@ORM\JoinColumn(name="BenefitGroup_id", referencedColumnName="id")}, inverseJoinColumns={@ORM\JoinColumn(name="BenefitGroupCategory_id", referencedColumnName="id", unique=true)})
*/
protected $BenefitGroupCategories;
// HERE I HAVE SOME IRRELEVANT GETTERS AND SETTERS
/**
* Constructor
*/
public function __construct()
{
$this->BenefitSubItems = new ArrayCollection();
$this->BenefitGroupCategories = new ArrayCollection();
}
/**
* Add BenefitGroupCategories
*
* @param \AppBundle\Entity\BenefitGroupCategory $benefitGroupCategories
* @return BenefitGroup
*/
public function addBenefitGroupCategory(\AppBundle\Entity\BenefitGroupCategory $benefitGroupCategories)
{
$this->BenefitGroupCategories[] = $benefitGroupCategories;
return $this;
}
/**
* Remove BenefitGroupCategories
*
* @param \AppBundle\Entity\BenefitGroupCategory $benefitGroupCategories
*/
public function removeBenefitGroupCategory(\AppBundle\Entity\BenefitGroupCategory $benefitGroupCategories)
{
$this->BenefitGroupCategories->removeElement($benefitGroupCategories);
}
/**
* Get BenefitGroupCategories
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getBenefitGroupCategories()
{
return $this->BenefitGroupCategories;
}
}
您还会注意到另一个实体,即BenefitItem,它是&#34;父亲&#34;福利集团。
和
<?php
// src/AppBundle/Entity/BenefitGroupCategory.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity()
* @ORM\Table(name="benefit_group_category")
* @UniqueEntity(fields={"name", "project"}, ignoreNull=false, message="Duplicated group category for this project")
*/
class BenefitGroupCategory
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string", length=50)
*/
protected $name;
/**
* @ORM\ManyToOne(targetEntity="Project")
*/
protected $project;
// HERE I HAVE SOME IRRELEVANT GETTERS AND SETTERS
}
在控制器中(你会看到几个嵌入式集合,哪些工作正常)我有:
/**
* @Route("/benefit/show/{projectID}", name="benefit_show")
*/
public function showAction(Request $request, $projectID)
{
$id=4; //the Id of the CVC to look for
$storedCVC = $this->getDoctrine()
->getRepository('AppBundle:CVC')
->find($id);
$form = $this->createForm(new CVCFormType(), clone $storedCVC);
$form->handleRequest($request);
if ($form->isValid())
{
$em = $this->getDoctrine()->getManager();
//$benefitGroupCategoryRepository = $this->getDoctrine()->getRepository('AppBundle:BenefitGroupCategory');
$formCVC = $form->getData();
$em->persist($formCVC);
foreach ($formCVC->getBenefitItems() as $formBI)
{
$newBI = new BenefitItem();
$newBI->setCVC($formCVC);
$newBI->setComment($formBI->getComment());
$em->persist($newBI);
foreach ($formBI->getBenefitGroups() as $formBG)
{
$newBG = new BenefitGroup();
$newBG->setBenefitItem($newBI);
$newBG->setBenefitGroupCategories($formBG->getBenefitGroupCategories());
$em->persist($newBG);
foreach ($formBG->getBenefitSubItems() as $formSI)
{
$newSI = new BenefitSubItem();
$newSI->setBenefitGroup($newBG);
$newSI->setComment($formSI->getComment());
$em->persist($newSI);
}
}
}
$em->flush();
}
return $this->render('benefit/show.html.twig', array(
'form' => $form->createView(),
));
}
问题是:在可视化中,它可以正确地显示表单(即使它没有正确检索类别。我可以选择类别,这没关系,但它没有检索到正确的一个。我是否必须在表单中设置默认值?
问题变得更糟当我总结它应该用所有嵌套的形式创建一个新实体(注意克隆)时。问题是它崩溃说:
Neither the property "BenefitGroupCategories" nor one of the methods
"addBenefitGroupCategory()"/"removeBenefitGroupCategory()",
"setBenefitGroupCategories()", "benefitGroupCategories()", "__set()" or
"__call()" exist and have public access in class
"AppBundle\Entity\BenefitGroup".
&#34;美女&#34;即使我在&#34; isValid&#34;中评论(讨厌的)部分也是它的行为完全相同。
我输了:(
答案 0 :(得分:0)
关于克隆您必须取消设置克隆实体的ID,请查看此处:https://stackoverflow.com/a/14158815/4723525
编辑:
是的,但PHP只做浅拷贝,你必须克隆其他对象。查看示例#1克隆http://php.net/manual/en/language.oop5.cloning.php中的对象。您必须通过定义__clone方法克隆您的对象(对于Doctrine低于2.0.2,您必须通过在克隆后调用自己的方法来执行此操作,因为代理定义了它自己的__clone方法)。例如:
function __clone() {
$oldCollection = $this->collection;
$this->collection = new ArrayCollection();
foreach ($oldCollection as $oldElement) {
$newElement = clone $oldElement;
// additional actions for example setting this object to owning side
$newElement->setParent($this);
$this->collection->add($newElement);
}
}