ManyToMany新值必须是\ Traversable的数组或实例,给定为“ NULL”

时间:2019-04-24 06:45:54

标签: symfony doctrine many-to-many symfony4

我在Symfony 4.2.6应用程序中有一个ManyToMany关系,我希望它可以为空。

所以我的第一个实体SpecialOffers如下:

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\SpecialOfferRepository")
 */
class SpecialOffer
{
    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\Neighbourhood", inversedBy="specialOffers")
     */
     private $neighbourhood;

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

    /**
     * @return Collection|Neighbourhood[]
     */
    public function getNeighbourhood(): Collection
    {
        return $this->neighbourhood;
    }

    public function addNeighbourhood(Neighbourhood $neighbourhood): self
    {
        if (!$this->neighbourhood->contains($neighbourhood)) {
            $this->neighbourhood[] = $neighbourhood;
        }

        return $this;
    }

    public function removeNeighbourhood(Neighbourhood $neighbourhood): self
    {
        if ($this->neighbourhood->contains($neighbourhood)) {
            $this->neighbourhood->removeElement($neighbourhood);
       }

       return $this;
   }
}

它与邻居类有关:

/**
 * @ORM\Entity(repositoryClass="App\Repository\NeighbourhoodRepository")
 */
class Neighbourhood implements ResourceInterface
{
    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\SpecialOffer", mappedBy="neighbourhood")
     */
    private $specialOffers;

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

        /**
     * @return Collection|SpecialOffer[]
     */
    public function getSpecialOffers(): Collection
    {
        return $this->specialOffers;
    }

    public function addSpecialOffer(SpecialOffer $specialOffer): self
    {
        if (!$this->specialOffers->contains($specialOffer)) {
            $this->specialOffers[] = $specialOffer;
            $specialOffer->addNeighbourhood($this);
        }

        return $this;
    }

    public function removeSpecialOffer(SpecialOffer $specialOffer): self
    {
         if ($this->specialOffers->contains($specialOffer)) {
            $this->specialOffers->removeElement($specialOffer);
            $specialOffer->removeNeighbourhood($this);
        }

        return $this;
    }
}

最后是

class SpecialOfferType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add(
                'neighbourhood',
                EntityType::class,
                [
                    'class' => Neighbourhood::class,
                    'label' => 'form.neighbourhood.label',
                    'translation_domain' => 'Default',
                    'required' => false,
                    'placeholder' => 'form.neighbourhood.all'
                ]
             );
        }
   }

但是,如果我没有在表单中为特殊优惠选择特定的邻居,则会出现以下错误:     Could not determine access type for property "neighbourhood" in class "App\Entity\SpecialOffer": The property "neighbourhood" in class "App\Entity\SpecialOffer" can be defined with the methods "addNeighbourhood()", "removeNeighbourhood()" but the new value must be an array or an instance of \Traversable, "NULL" given.

无论如何,我都能做到这一点,以便我的特价商品包含邻域和数组,或者仅仅是null吗?

我觉得自己正在忽略一些非常明显的东西,任何帮助将不胜感激

2 个答案:

答案 0 :(得分:3)

Test =>

DataTransformer

答案 1 :(得分:1)

由于您在实体上的字段都是多对多的,因此需要一个数组(或相似的字段),并且表单字段为EntityType,它将返回一个预期类型或{{1 }},我觉得有些不对称。

我会考虑从一开始就使用CollectionType或至少将表单上的multiple选项设置为null,以便返回值是一个数组。

另一种选择是在表单字段中添加true,这会将null变成一个空数组,将一个实体变成一个实体的数组,反之亦然。