Новое значение ManyToMany должно быть массивом или экземпляром \ Traversable, с учетом «NULL» - PullRequest
1 голос
/ 24 апреля 2019

У меня есть отношение ManyToMany в моем приложении Symfony 4.2.6, и я хотел бы, чтобы это было возможно, чтобы это было нулевым.

Итак, мой первый объект 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.

Могу ли я в любом случае сделать так, чтобы мое специальное предложение содержало либо массив окрестностей, либо просто ноль?

Я чувствую, что упускаю что-то действительно очевидное, любая помощь будет принята с благодарностью

Ответы [ 2 ]

3 голосов
/ 24 апреля 2019

Тест =>

$builder
            ->add(
                'neighbourhood',
                EntityType::class,
                [
                    'class' => Neighbourhood::class,
                    'label' => 'form.neighbourhood.label',
                    'translation_domain' => 'Default',
                    'required' => false,
                    'multiple' => true,
                    'placeholder' => 'form.neighbourhood.all'
                ]
             );
1 голос
/ 24 апреля 2019

Поскольку ваши поля в сущностях имеют много-много-много значений, то есть ожидается, что массив (или аналогичный) и поле формы имеют значение EntityType, которое вернет одну сущность ожидаемого типа или null, я чувствую, что есть какая-то форма асимметрии.

Я хотел бы рассмотреть вопрос об использовании CollectionType с самого начала или, по крайней мере, установить параметр multiple в форме на true, чтобы возвращаемое значение было массив.

Другой вариант - добавить DataTransformer в поле формы, которое превращает ноль в пустой массив, а одну сущность в массив из одной сущности, и наоборот.

...