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

时间:2017-03-28 20:11:01

标签: 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;
    }
}

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

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

然后我有一个每个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,
    ));
}

有关额外信息,请参阅我的表单构建器:

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

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

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

2 个答案:

答案 0 :(得分: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;
    }

此条件只是说明如果还没有孩子,请添加孩子,或者如果孩子不在$this->childs数组中,则添加它。

答案 1 :(得分:1)

因为您可以通过module.exports = { dbPath: function(req, res, next){ var login = req.body.login; console.log('login - ', login); if (login === 'demo@mysite.com'){ req.dbPath = 'DB_SAND'; } else { req.dbPath = 'DB_ALPHA'; } next(); } }; 作为Doctrine集合访问$childs

removeChild

因此,在构造函数中,您应该首先初始化您的childs集合。

/**
 * Remove child
 *
 * @param \AppBundle\Entity\Child $child
 */
public function removeChild(\AppBundle\Entity\Child $child)
{
    $this->childs->removeElement($child);
}

为了避免重复的孩子,你需要在添加到集合之前检查现有的。

public function __construct()
{
    $this->childs = new ArrayCollection();
}