Добавляйте дочерние объекты к родительским только в том случае, если они еще не существуют
Я занят разработкой действия для родителя,которое должно добавить количество детей, заданных пользователем.
У детей есть 3 свойства, и, сочетая их, каждый ребенок всегда должен быть уникальным.
Я использую Symfony и Doctrine, и мой базовый родительский класс выглядит следующим образом:
class Parent { /** * @var Child[]|ArrayCollection * * @ORM\OneToMany(targetEntity="Child", mappedBy="parent") * @ORM\OrderBy({"dateCreated": "DESC"}) */ private $childs; /** * Add child * * @param \AppBundle\Entity\Child $child * * @return Parent */ public function addChild(\AppBundle\Entity\Child $child) { $this->childs[] = $child; $child->setParent($this); return $this; } /** * Remove child * * @param \AppBundle\Entity\Child $child */ public function removeChild(\AppBundle\Entity\Child $child) { $this->childs->removeElement($child); } /** * Get childs * * @return \Doctrine\Common\Collections\Collection */ public function getChilds() { return $this->childs; } }
Мой детский класс выглядит так (опять же очень просто):
class Child { /** * @var int * * @ORM\Column(name="cupboard", type="integer") */ private $cupboard; /** * @var int * * @ORM\Column(name="shelf", type="integer") */ private $shelf; /** * @var int * * @ORM\Column(name="item", type="integer") */ private $item; /** * @var Parent * * @ORM\ManyToOne(targetEntity="Parent", inversedBy="childs") * @ORM\JoinColumns({ * @ORM\JoinColumn(name="parent_id", referencedColumnName="id") * }) */ private $parent; /** * Set cupboard * * @param string $cupboard * * @return Child */ public function setCupboard($cupboard) { $this->cupboard = $cupboard; return $this; } /** * Get cupboard * * @return int */ public function getCupboard() { return $this->cupboard; } /** * Set shelf * * @param string $shelf * * @return Child */ public function setShelf($shelf) { $this->shelf = $shelf; return $this; } /** * Get shelf * * @return int */ public function getShelf() { return $this->shelf; } /** * Set item * * @param string $item * * @return Child */ public function setItem($item) { $this->item = $item; return $this; } /** * Get item * * @return int */ public function getItem() { return $this->item; } /** * Set parent * * @param Parent $parent * * @return Child */ public function setParent(Parent $parent) { $this->parent = $parent; return $this; } /** * Get parent * * @return Parent */ public function getParent() { return $this->parent; } }
Затем у меня есть действие для каждого родительского объекта (вроде того же, что и действие редактирования), которое должно создавать для него дочерних объектов. Когда я нажимаю на ссылку (для конкретного родителя), создается форма с тремя полями ввода:
- Буфет
- Полка
- Количество предметов
Затем пользователь должен указать целыми числами, сколько предметов он хочет добавить в какой шкаф и на какую полку. Если элемент (целое число) уже существует в данном шкафу на данной полке, он не должен делать это снова, но первое следующее доступное целое число должно быть использовано для элемента.
Как я могу сделать это как можно проще? Я понимаю, что могу использовать функцию addChild из родительского класса, но не знаю, как это сделать.
Что я уже пробовал:
До сих пор я пытался создать массив и сгруппировать все элементы в соответствии со шкафом и полкой, а затем, если элемент не существует в этом массиве, он должен быть создан.
Это мой код:
public function addItemAction(Request $request, $id = null){ $parent = $this->admin->getSubject(); if (!$parent) { throw new NotFoundHttpException(sprintf('Unable to find the object with id: %s', $id)); } $em = $this->getDoctrine()->getManager(); $form = $this->createForm(AddItemType::class); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $kids = $popUnit->getChilds(); $formParams = $request->request->get('add_item'); $units = array(); foreach ($kids as $kid) { $units[$kid->getCupboard()][$kid->getShelf()][$kid->getItem()] = $kid->getItem(); } $givenShelf = $units[$formParams['cupboard']][$formParams['shelf']]; for ($i = 1; $i <= $formParams['itemAmount']; $i++) { if (!in_array($i, $givenShelf)) { $child = new Child(); $child->setParent($parent); $child->setCupboard($formParams['cupboard']); $child->setShelf($formParams['shelf']); $child->setItem($i); $em->persist($child); $em->flush(); } } return new RedirectResponse($this->admin->generateUrl('show', array('id' => $parent->getId()))); } return $this->render('AppBundle:Parent:add_childs.html.twig', array( 'form' => $form->createView(), 'parent' =>$parent, )); }
Для получения дополнительной информации, вот как выглядит мой конструктор форм:
public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('cupboard', NumberType::class) ->add('shelf', NumberType::class) ->add('itemAmount', NumberType::class, array('label' => 'Number of Items')) ; }
Как я могу сделать это действие как можно более простым с тем, чтобы убедиться, что только уникальные предметы добавляются на полку в шкафу для родителей. Я не могу изменить ни свойства, ни классы. Я должен работать с этим. Я не хочу использовать какой-либо другой сложный способ, такой как создание каких-либо слушателей или других функций until.
Я надеюсь, что хорошо объяснил свою ситуацию, и я надеюсь, что кто-то может помочь мне с хорошей обратной связью.