Gedmo Doctrine Extensions Tree无法在没有父

时间:2015-07-02 15:08:29

标签: forms symfony nested-sets doctrine-extensions

我正在使用Gedmo Doctrine Extensions将类别作为嵌套集处理。 我正在构建一个REST API,我有一个创建类别的路径。 我希望能够创建根类别或子类别。 这是实体

<?php
namespace AppBundle\Entity;

use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;

/**
 * @Gedmo\Tree(type="nested")
 * @ORM\Table(name="bo_categories")
 * use repository for handy tree functions
 * @ORM\Entity(repositoryClass="Gedmo\Tree\Entity\Repository\NestedTreeRepository")
 */
class Category
{
    /**
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue
     */
    private $id;

    /**
     * @ORM\Column(name="name", type="string", length=64)
     */
    private $name;

    /**
     * @Gedmo\TreeLeft
     * @ORM\Column(name="lft", type="integer")
     */
    private $lft;

    /**
     * @Gedmo\TreeLevel
     * @ORM\Column(name="lvl", type="integer")
     */
    private $lvl;

    /**
     * @Gedmo\TreeRight
     * @ORM\Column(name="rgt", type="integer")
     */
    private $rgt;

    /**
     * @Gedmo\TreeRoot
     * @ORM\Column(name="root", type="integer", nullable=true)
     */
    private $root;

    /**
     * @Gedmo\TreeParent
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")
     */
    private $parent;

    /**
     * @ORM\OneToMany(targetEntity="Category", mappedBy="parent")
     * @ORM\OrderBy({"lft" = "ASC"})
     */
    private $children;

    public function getId()
    {
        return $this->id;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setParent(Category $parent = null)
    {
        $this->parent = $parent;
    }

    public function getParent()
    {
        return $this->parent;
    }
}

这是表格

<?php

namespace AppBundle\Form\Type\Classification;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class CategoryFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name')
                ->add('parent', 'entity', array(
                        'class'    => 'AppBundle:Category',
                        'property' => 'id',
                    ))
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class'      => 'AppBundle\Entity\Category',
            'csrf_protection' => false,
        ));
    }

    public function getName()
    {
        return 'api_category';
    }
}

这是控制器

/**
     * @Route("/create")
     * @Security("has_role('ROLE_SUPER_ADMIN')")
     * @Rest\View
     */
    public function postCreateAction(Request $request)
    {
        $categoryManager = $this->get('app.manager.category');

        $category = $categoryManager->createNew();

        $form = $this->createForm(new CategoryFormType(), $category);

        // $category->setParent(10);

        $form->handleRequest($request);

        if ($form->isValid()) {

            $categoryManager->save($category);

            return new Response('', 201);
        } else {
            return $this->view($form, 400);
        }

    }

如果我想创建一个子类别,它可以正常工作。但是,如果我想在不删除表单中的“父”字段的情况下创建根类别,我会收到此错误

An exception occurred while executing 'SELECT b0_.id AS id0, b0_.name AS name1, b0_.lft AS lft2, b0_.lvl AS lvl3, b0_.rgt AS rgt4, b0_.root AS root5, b0_.parent_id AS parent_id6 FROM bo_categories b0_ WHERE b0_.id IN (?)' with params [""]:\n\nSQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for integer: "", "class": "Doctrine\DBAL\DBALException

为什么会出现此错误?表单中的“父”值是否为空/ null?

1 个答案:

答案 0 :(得分:0)

parent NULL绝对没有问题。另一方面,您当前的映射不允许这样做。

首先,您应修改$parent

的映射
@ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")

应该允许null值:

@ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE", nullable=true)

当您更改映射时,不要忘记运行app/console doctrine:schema:update --force

接下来,您的表单看起来没问题,但它遗漏了一个属性 - empty_value。这不会强迫您选择父类别。

->add('parent', 'entity', array(
      'class'    => 'AppBundle:Category',
      'property' => 'id',
))

应该是这样的:

->add('parent', 'entity', array(
      'class'    => 'AppBundle:Category',
      'property' => 'id',
      'empty_value' => '-- Select parent --'
))

这应该添加带 no 值的额外选项,默认情况下应该选择(创建新类别时)。由于您的字段属于entity类型,因此您也会看到所有类别(当您需要选择父类别时)。

这应该可以解决问题,试一试。