У меня есть отношение 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.
Могу ли я сделать так, чтобы мое специальное предложение либо содержало и массив районов, либо просто нулевое значение?
Я чувствую, что упускаю из виду что-то действительно очевидное, любая помощь будет принята с благодарностью




Поскольку ваши поля в сущностях являются многими ко многим, поэтому ожидается массив (или аналогичный), а поле формы имеет значение EntityType, которое вернет одну сущность ожидаемого типа или null, я чувствую, что есть некоторая форма асимметрия.
Я бы рассмотрел возможность использования CollectionType с самого начала или, по крайней мере, установить для параметра multiple в форме значение true, чтобы возвращаемое значение было массивом.
Другим вариантом может быть добавление DataTransformer к полю формы, которое превращает ноль в пустой массив и один объект в массив из одного объекта, и наоборот.
Тест =>
$builder
->add(
'neighbourhood',
EntityType::class,
[
'class' => Neighbourhood::class,
'label' => 'form.neighbourhood.label',
'translation_domain' => 'Default',
'required' => false,
'multiple' => true,
'placeholder' => 'form.neighbourhood.all'
]
);