Почему не инициализируется ArrayCollection, не сопоставленный с доктриной?

#forms #symfony #doctrine #arraycollection

#формы #symfony #доктрина #arraycollection

Вопрос:

Моя установка представляет собой приложение Symfony 3.4 с типичным ‘ ManyToMany ‘-отношением с дополнительными полями, что-то вроде этого:

 Entity Article
Entity Specialty
Entity ArticleSpecialtyRelation
  

В Form для Article ManyToMany я хотел, чтобы это выглядело так, как если бы это было EntityType отношение, отображаемое как multiple=true с expanded=true и Specialty , так что все записи в,, отображаются в виде флажков.

Для достижения этой цели я создал свойство, не отображенное в orm specialties , которое является ArrayCollection, инициализируется в конструкторе и имеет средство получения, суммирования и удаления.

  /**
 *
 * @var ArrayCollection;
 * 
 */
 protected $specialties;

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

 /**
 * @return Collection|Specialty[]
 */
public function getSpecialties()
{
    return $this->specialties;
}

/**
 * @param Specialty $specialties
 */
public function addSpecialties(Specialty $specialties)
{
    $this->specialties->add($specialties);

}

/**
 * @param Specialty $specialties
 */
public function removeSpecialties(Specialty $specialties)
{
    $this->specialties->removeElement($specialties);
}
  

Это свойство используется для отображения Specialty объекта в виде флажков:

 add('specialties', EntityType::class,array(
            'class' => Specialty::class,
            'expanded'=>true,
            'multiple'=>true,
            'label'=>'Specialties',
            'required' => false,
            'mapped'=>true,
        ));
  

Чтобы заполнить его данными из SpecialtyRelation я добавил PreSetData Formevent :

  $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
            $form = $event->getForm();
            $article = $event->getData();

            if ($article instanceof Article) {
                $form->get('specialties')->setData($article->getUsedSpecialties());
            }
        });
  

Используемый метод получения $artikel просто выполняет итерацию $article->getArtikelSpecialties и возвращает коллекцию Specialty .

Все это работает до отправки. Поскольку formfield находится mapped=true где handleRequest($form) -то там, где объект насыщен данными формы, он взрывается при вызове сумматора для $specialty :

Call to a member function add() on null

Потому что, как я только что узнал, Constructor никогда не вызывается Doctrine и, очевидно, инициализирует все ORM- ArrayCollections но не ArrayCollection для не отображенного свойства specialties

Конечно, я могу проверить, инициализировано ли ArrayCollection в сумматоре и удалении, и инициализировать его там, если оно равно null, но это просто кажется немного халтурным в уже, по крайней мере, хакерской настройке, и мне интересно, не совсем ли глупа моя настройка, тем более что я не нашел никого, кто пытался бы это сделать (или у кого возникли проблемы с этим) здесь или где-либо еще.

Есть ли лучшее решение для этого или я должен просто проверить ArrayCollection в сумматоре и удалении и жить долго и счастливо с тех пор? Кроме того, просто любопытно, есть ли какой-либо другой способ инициализировать ArrayCollection ?

P.S. Если в именах есть опечатки, это потому, что я перевел имена на английский.

Частичная трассировка стека

SymfonyComponent DebugException FatalThrowableError: вызов функции-члена add() при null

в src /Test /Bundle /TestBundle/Entity/Article.php:312 в Test Bundle TestBundleEntity Article->addSpecialties(объект (специальность)) (поставщик / symfony / symfony/src /Symfony/Component /PropertyAccess/PropertyAccessor.php:674) в SymfonyComponent PropertyAccessorPropertyAccessor->writeCollection(массив (объект (статья), object(Статья)), ‘specialties’, object (ArrayCollection), ‘addSpecialties’, ‘removeSpecialties’) (поставщик / symfony / symfony/src /Symfony/Component /PropertyAccess/PropertyAccessor.php:622) в SymfonyComponent PropertyAccessPropertyAccessor-> Свойства записи(массив (объект (статья), object(Статья)), ‘specialties’, object (ArrayCollection)) (поставщик / symfony /symfony/src /Symfony/Component /PropertyAccess/PropertyAccessor.php:216) в SymfonyComponent PropertyAccessPropertyAccessor->setValue(объект (статья), объект (PropertyPath), объект (ArrayCollection)) (поставщик / symfony / symfony/src /Symfony/Компонент / Форма / Расширение / Ядро / DataMapper /PropertyPathMapper.php: 86) в SymfonyComponentFormExtensionCoreDataMapperPropertyPathMapper->mapFormsToData(object(RecursiveIteratorIterator) , объект (статья)) (поставщик / symfony/symfony/src/Symfony/Component/Form/Form.php:636) в SymfonyComponentFormForm->submit(array(), true) (поставщик / symfony/symfony/src /Symfony/Component/Form/Form.php:580)

Комментарии:

1. it explodes when the Adder for $specialty is called имейте в виду, что, сформулировав это таким образом, ваш вопрос также может автоматически взорваться. Скорее добавьте трассировку исключения в свой вопрос.

2. Спасибо! Я, конечно, возражаю 🙂 и добавил точную ошибку и частичную трассировку стека с интересным битом.