我在通过表单保存带有多对多关系的实体时遇到问题。
我无法保存在关系“mappedBy”一侧的字段。
以下代码未将任何内容保存到数据库中,也没有抛出任何错误:
// Entity/Pet
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Customer", mappedBy="pet", cascade={"persist"})
*/
private $customer;
/**
* Set customer
*
* @param \AppBundle\Entity\Customer $customer
* @return Pet
*/
public function setCustomer($customer)
{
$this->customer = $customer;
return $this;
}
// Entity/Customer
/**
* @var Pet
*
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\Pet", inversedBy="customer", cascade={"persist"})
* @ORM\JoinTable(name="customer_pet",
* joinColumns={
* @ORM\JoinColumn(name="customer_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="pet_id", referencedColumnName="id")
* }
* )
*/
private $pet;
// PetType.php
$builder->add('customer', 'entity',
array(
'class' => 'AppBundle:Customer',
'property' => 'firstname',
'empty_value' => 'Choose owner',
'multiple' => true
));
它是反向工作的。所以,如果我从CustomerType保存某些东西,一切都正常。编辑:下面的解决方案对我有用,但几天后我发现了一个问题。如果表单提交的值已经保存在数据库中,则Symfony将抛出错误。为了防止这种情况,我必须检查是否已将给定客户分配给宠物。当前分配的客户的检查必须在函数开始时进行,而不是在表单提交后进行,因为由于某种原因,在提交后Pet()对象包含提交的值,而不仅仅是数据库中存在的值。所以在开始时,我将所有已分配的客户放入数组中。
$em = $this->getDoctrine()->getManager();
$pet = $em->getRepository('AppBundle:Pet')->find($id);
$petOriginalOwners = array();
foreach ($pet->getCustomer() as $petCustomer)
{
$petOriginalOwners[] = $petCustomer->getId();
}
提交表单后,我检查了提交的ID是否在数组中
if ($form->isValid())
{
foreach ($form['customer']->getData()->getValues() as $v)
{
$customer = $em->getRepository('AppBundle:Customer')->find($v->getId());
if ($customer && !in_array($v->getId(), $petOriginalOwners) )
{
$customer->addPet($pet);
}
}
$em->persist($pet);
$em->flush();
return $this->redirect($this->generateUrl('path'));
}
EntityType
的托管表单,对于“mappedBy”方面在表单上使用"by_reference"
=false
就足够了。-我只是没有注意到"by_reference"
对于EntityType
也是可用的。(我以为它只适用于CollectionType
和ChoiceType
)。 - Adambean"by_reference"
在EntityType
中已经不再起作用了。尽管它继承自具有此功能的ChoiceType
,但我可以确认,在Symfony 3.4.22上为“mappedBy”侧表单设置"by_reference"
为false
不再起作用。(我在两个不同的项目上都试过了。) - Adambean