Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • Add children objects to a parent only if they don't yet exist

    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 480
    Answer it

    I am busy developing an action for parent that should add a number of children given by the user input.

    The children have 3 properties, and combining them, each child should always be unique.

    I make use of Symfony and Doctrine and my basic parent class looks like this:

    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;
        }
    }

    My child class look like this (again really basic):

    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;
        }
    }

    Then I have an action per parent object (kind of the same as an edit action) that has to create children for it. When I click the link (for the specific parent) a form is generated that has three input fields:

    • Cupboard
    • Shelf
    • Number of items

    The user then has to specify with integers how many items he wants to add in what cupboard and what shelf. If the item (integer) already exist in that given cupboard on that given shelf it should not make it again, but the first next available integer should be used for item.

    How can I make this as simple as possible? I understand I can use the addChild function from the Parent class, but I'm not sure how.

    What I have tried so far is to create an array and group all items according to cupboard and shelf and then if the item does not exist in that array it should be created.

    This is my code:

    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,
        ));
    }

    For extra information, this is how my form builder looks:

    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'))
        ;
    }

    How can I make this action as simple as possible with the fact to make sure only unique items is added to a shelf in a cupboard for the parent. I can't change the properties nor the classes. I have to work with this. I don' want to use any other complex way like creating any listeners or other until functions.

    I hope I've explained my situation well and I hope somebody can help me with some good feedback.

 0 Answer(s)

Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: