У меня есть проблема с сохранением сущности с помощью отношений ManyToMany.Форма Symfony не сохраняет объект с отношением ManyToMany
Я не могу сохранить поля, которые находятся на стороне «mappedBy».
Код ниже не спасает ничего к базе данных и не trowing ошибки:
// 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, все работает.
EDIT:
Решение ниже работал для меня, но после нескольких дней я обнаружил проблему с этим решением. Если форма будет отправлена со значением, которое уже было сохранено в базе данных, тогда Symfony вытолкнет ошибку. Чтобы предотвратить, что я должен был проверить, был ли данный клиент уже назначен домашнему животному.
Проверка назначенных клиентов должна выполняться в начале функции, а не после отправки формы, поскольку по какой-либо причине после представления объекта Pet() представлены представленные значения не только те, что присутствуют в db.
Так в начале я гнал все уже присвоенные клиентов к массиву
$em = $this->getDoctrine()->getManager();
$pet = $em->getRepository('AppBundle:Pet')->find($id);
$petOriginalOwners = array();
foreach ($pet->getCustomer() as $petCustomer)
{
$petOriginalOwners[] = $petCustomer->getId();
}
И после отправки формы я проверил, если представленные идентификаторы в массиве
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'));
}
Спасибо, что работает, я не думаю, что в этом решении есть что-то не так, это просто. Если он работает и не добавляет каких-либо уязвимостей в систему, то ЭТО - ПРАВИЛЬНЫЙ ПУТЬ. Еще раз спасибо! – Draco