Доктрина 2 не сохраняла отношения от владения одной до многих
У меня есть этот код
// ONE to many Bidir -- inverse side
/**
* @ORM\OneToMany(targetEntity="Item", mappedBy="Room", cascade={"persist"})
**/
protected $items;
Другая сторона
// ONE to many Bidir-- own side
/**
* @ORM\ManyToOne(targetEntity="Room", inversedBy="items")
* @ORM\JoinColumn(name="room_id", referencedColumnName="id")
**/
protected $room;
Моя проблема в том, что я перехожу на страницу с деталями, и я выбираю Room, затем я могу видеть элементы preselecetd на странице Room
Но если я перейду на страницу "Комната", и я попытаюсь отобразить много элементов, то они не сохраняются.
EDIT: Я видел, что это происходит только для корабля отношения OneToMany. Для Manyto Many они отлично работают
EDIT2:
Я говорю о бэкэнд-области, где у меня есть форма и поле выбора, где я могу выбрать несколько элементов. Этот код/контроллеры/CRUD формы кодируются доктриной. SO, мне не нужно добавлять дополнительную функцию. В любом случае это мой код контроллера
$editForm = $this->createForm(new RoomType(), $entity);
$request = $this->getRequest();
$editForm->bindRequest($request);
if ($editForm->isValid()) {
$em->persist($entity);
$em->flush();
Когда я пытаюсь пройти через контроллер, как этот
foreach($entity->getItems() as $item)
echo $item;
Затем я вижу все предметы там. Таким образом, это означает, что все предметы находятся в основном объекте, но не сохраняются. я не знаю почему.
Если есть проблема, обратная сторона. Как я могу связать отношения из-за обратного и обратного к владению
Ответы
Ответ 1
Ваш код неверен, основываясь на ваших комментариях в аннотациях.
Это владеющая сторона, потому что вы указываете атрибут inversedBy
:
/**
* ONE to many Bidir-- Inverse side
* @ORM\ManyToOne(targetEntity="Room", inversedBy="items")
* @ORM\JoinColumn(name="room_id", referencedColumnName="id")
**/
protected $room;
Это обратная сторона (потому что у нее есть атрибут mappedBy
):
/**
* ONE to many Bidir -- owning side
* @ORM\OneToMany(targetEntity="Item", mappedBy="Room", cascade={"persist"})
**/
protected $items;
Итак, ваш код говорит: Item
является стороной-обладателем, Room
является обратной стороной.
владеющая сторона двунаправленного отношения должна ссылаться на ее обратную сторону используйте атрибута inversedBy OneToOne, ManyToOne или ManyToMany. Атрибут inverseedBy обозначает поле в сущности, которая является обратной стороной отношения.
Чтобы сделать его более чистым:
Собственная сторона должна использовать атрибут inversedBy OneToOne, ManyToOne или ManyToMany. Атрибут inverseedBy содержит имя поля ассоциации на обратной стороне.
В то время как для обратной стороны:
обратная сторона двунаправленного отношения должна ссылаться на ее владеющей стороной используйте атрибута mappedBy OneToOne, OneToMany или ManyToMany. Атрибут mappedBy определяет поле в объекте, являющемся владельцем отношения.
И снова:
Обратная сторона должна использовать атрибут mappedBy OneToOne, OneToMany или ManyToMany. Атрибут mappedBy содержит имя поля ассоциации на стороне владельца.
Плюс еще одно важное соображение:
ManyToOne всегда является обладающей двунаправленной ассоциацией.
OneToMany всегда является обратной стороной двунаправленной связи
Таким образом, для сохраняющихся элементов с обратной стороны (комнаты) вы должны проверить, какой элемент был выбран/отменен, и если номер уже содержит этот элемент или нет.
Ответ 2
Просто используйте петлю для установки комнаты. Элемент является стороной, и вы редактируете обратную сторону (комнату).
Symfony2 никогда не обновляет сторонние стороны при редактировании обратного.
Простейшим решением для вас является использование цикла перед сохранением комнаты:
foreach($entity->getItems() as $item){
$item->setRoom($room);
}
и каскадом с обратной стороны:
/**
* @ORM\OneToMany(targetEntity="Item", mappedBy="Room", cascade={"persist"})
**/
protected $items;
Для моих проектов я сделал многоразовое решение на основе слушателей событий коллекции.
Если у вас есть время и навыки, я рекомендую вам сделать то же самое