仅当子对象尚不存在时才将它们添加到父对象

Jac*_*mer 10 php symfony

我正在忙着开发一个动作parent,应该添加一些由用户输入给出的子项.

孩子们有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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的孩子班看起来像这样(再次非常基本):

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我有一个每个parent对象的动作(与编辑动作相同)必须为它创建子动作.当我单击链接(针对特定父级)时,将生成一个包含三个输入字段的表单:

  • 橱柜
  • 东西的个数

然后,用户必须用整数指定他想要在橱柜和货架中添加多少物品.如果项目(整数)已存在于给定货架上的给定橱柜中,则不应再次进行,但第一个下一个可用整数应该用于项目.

我怎样才能让它变得尽可能简单?我明白我可以使用课堂上的这个addChild功能Parent,但我不知道怎么做.

到目前为止我所尝试的是创建一个数组并根据橱柜和架子对所有项目进行分组,然后如果该项目不存在于该数组中则应该创建它.

这是我的代码:

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,
    ));
}
Run Code Online (Sandbox Code Playgroud)

有关其他信息,这是我的表单构建器的外观:

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'))
    ;
}
Run Code Online (Sandbox Code Playgroud)

如何确保此操作尽可能简单,以确保只有唯一的项目才会添加到父级橱柜的架子中.我不能改变属性和类.我必须这样做.我不想使用任何其他复杂的方式,比如创建任何监听器或其他功能.

我希望我已经很好地解释了我的情况,我希望有人可以帮助我提供一些好的反馈.

Wes*_*row 4

您是正确的,您可以像这样修改类addChild的函数:Parent

    /**
     * Add child
     *
     * @param \AppBundle\Entity\Child $child
     *
     * @return Parent
     */
    public function addChild(Child $child)
    {
        if ( ! is_array($this->childs) || ! in_array($child, $this->childs)) {
            $this->childs[] = $child;
            $child->setParent($this);
        }
        return $this;
    }
Run Code Online (Sandbox Code Playgroud)

该条件只是说明,如果还没有子级,则添加子级,或者如果子级尚不存在于数组中,$this->childs则添加它。