Symfony3表单复选框保存错误

时间:2017-11-18 12:35:21

标签: php forms symfony checkbox doctrine

我试图查看Google,但没有找到任何有这样问题的人。我想我做的一切都像文档指南,但我想我错过了什么

所以我有一个带有这样的复选框的表单:

    $builder->add(
        'productTypes',
        EntityType::class,
        array(
            'label'        => 'Available for products',
            'class'        => 'ShopBundle:ProductType',
            'choice_label' => 'name',
            'multiple'     => true,
            'expanded'     => true,
            'by_reference' => false,
        )
    );

当我编辑所有内容顺利时,我可以编辑现有条目并选中或取消选中此复选框,它可以正常保存,但是当我尝试添加新对象时,我收到错误:

  

PHP致命错误:在null中调用成员函数add()   C:\ XAMPP \ htdocs中\ uniacar-SF的\ src \ ShopBundle \实体\ ProductAttribute.php   在第188行

这是我的控制器动作:

public function editAction(Request $request, $id = null)
{
    $this->setMenuTab('cars', 'admin');
    $productTypes = new ArrayCollection();

    if (!empty($id)) {
        $attribute = $this->getRepo(ProductAttribute::class)->find($id);
        $this->setTitle('admin.cars.attributes.edit');

        foreach ($attribute->getProductTypes() as $value) {
            $productTypes->add($value);
        }
    } else {
        $attribute = new ProductAttribute();
        $this->setTitle('admin.cars.attributes.new');
    }

    $form = $this->createForm(ProductAttributeForm::class, $attribute);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $attribute = $form->getData();

        foreach ($productTypes as $productType) {
            if (false === $attribute->getProductTypes()->contains($productType)) {
                $productType->getAttributes()->removeElement($attribute);
                $this->db()->persist($productType);
            }
        }

        $this->db()->persist($attribute);
        $this->db()->flush();

        return $this->redirectToRoute('carAdmin', array('tab' => 'attributes'));
    }

    $this->setVariables(
        array(
            'form'      => $form->createView(),
            'attribute' => $attribute,
        )
    );

    return $this->response();
}

$this->db()$this->getDoctrine()->getManager()

的捷径

这是ProductAttribute的定义部分,与ProductType相关:

/**
 * Constructor
 */
public function __construct() {
    $this->productTypes = new ArrayCollection();
}

/**
 * Many Attributes have Many ProductTypes
 * @ORM\ManyToMany(targetEntity="ProductType", mappedBy="attributes", cascade={"persist"})
 */
private $productTypes;

/**
 * @param ProductType $productType
 */
public function addProductType(ProductType $productType)
{
    $this->productTypes->add($productType);
    $productType->addProductAttribute($this);
}

/**
 * @param ProductType $productType
 */
public function removeProductType(ProductType $productType)
{
    $this->productTypes->removeElement($productType);
}

此外,ProductType Entity的一部分与ProductAttribute相关:

/**
 * Constructor
 */
public function __construct() {
    $this->attributes = new ArrayCollection();
}

/**
 * Many ProductTypes have Many Attributes
 * @ORM\ManyToMany(targetEntity="ProductAttribute", inversedBy="productTypes")
 * @ORM\JoinTable(name="product_type_to_attribute")
 */
private $attributes;


/**
 * @param ProductAttribute $attribute
 */
public function addProductAttribute(ProductAttribute $attribute)
{
    if (!$this->attributes->contains($attribute)) {
        $this->attributes->add($attribute);
    }
}

public function removeProductAttribute(ProductAttribute $attribute)
{
    $this->attributes->removeElement($attribute);
}

我尝试按照Symfony嵌入表单教程(How to Embed a Collection of Forms) 我知道在这种情况下没有嵌入的集合(我在这个实体中有另一个字段,它是嵌入的表单集合,它工作得很好)但是根据我的理解,在这种情况下关系是相同的,它是多对多的所以我必须告诉Symfony如何处理关系,添加和删除对象。 我倾倒了POST中的数据,但它与版本相同 - productType就在那里。任何想法为什么我会收到此错误?

它在行$this->productTypes->add($productType);

中的ProductAttribute实体中触发

编辑: 我更新了控制器代码,搞砸了关于从ProductAttribute取消链接ProductType的逻辑。但是它对问题没有任何影响,当我尝试保存新对象时仍然是相同的500错误。

EDIT2: 我无法从Symfony获得堆栈跟踪,因为我得到普通的浏览器500错误(可能是因为它是致命错误,我在apache日志中找到它)。创建错误的控制器中的行是$form->handleRequest($request);

2 个答案:

答案 0 :(得分:1)

这不是表单集合,但您使用的是特定于集合的方法,这不是一个好习惯,但是,在创建新对象时,您不需要以下代码。

foreach ($productTypes as $value) {
    if (false === $attribute->getProductTypes()->contains($value)) {
            $attribute->getProductTypes()->removeElement($value);
    }
}

答案 1 :(得分:0)

所以,我还没有找到问题的解决方案,但我通过修复项目的文件结构(将一般资源文件夹中的资源包移动到Bundle&#39s资源文件夹)以某种方式解决了它。我不知道为什么这解决了这个问题,甚至是工作但不正确的文件夹结构和提交表单之间的联系,但现在它可以工作,所以我会将问题标记为已回答。