В старом проекте с Symfony 2.8,
у меня есть 3 типа значений (computedValue, manualData, probeData) У меня есть имя объекта «dataSource», которое содержит 3 источника, но можно установить только один (2 другие установлены в null)
У меня есть другая сущность, которая содержит 3 DataSource и 3 ArrayCollection of DataSource.
Я создаю свою форму следующим образом:
...
->add('dsRef1', DataSourceType::class, [
'site' => $site,
'multiple' => false,
'label_format' => 'form.%name%Ref1',
])
->add('dsList1', DataSourceType::class, [
'site' => $site,
'multiple' => true,
'label_format' => 'form.%name%List1',
])
... ( 3 time , dsRef1 - 3 , dlList1 - 3 )
Мой DataSourceType:
$builder
// This value is added for force symfony to think the form is submit when the form need to be empty
->add('hiddenCrapValue', HiddenType::class, [
'required' => false,
'mapped' => false,
'attr' => [
'front-attr' => [
'render' => 'hidden',
],
],
])
->add(DataSourceInterface::DATA_SOURCE, ChoiceType::class, [
'choices' => $site->getDataSources(),
'choices_as_values' => true,
'multiple' => $multiple,
'mapped' => false,
'required' => false,
'label_format' => $labelFormat,
])
->add(DataSourceInterface::PROBE_DATA, EntityType::class, [
'class' => ProbeData::class,
'required' => false,
'multiple' => $multiple,
'attr' => [
'front-attr' => [
'render' => 'hidden',
],
],
])
->add(DataSourceInterface::MANUAL_DATA, EntityType::class, [
'class' => ManualData::class,
'required' => false,
'multiple' => $multiple,
'attr' => [
'front-attr' => [
'render' => 'hidden',
],
],
])
->add(DataSourceInterface::COMPUTED_VALUE, EntityType::class, [
'class' => ComputedValue::class,
'required' => false,
'multiple' => $multiple,
'attr' => [
'front-attr' => [
'render' => 'hidden',
],
],
])
;
Это работает для моего ref (dsRef1, dsRef2, dsRef3) ... Но когда я добавляю dsList1, у меня появляется ошибка, которая говорит:
"The form's view data is expected to be an instance of class EnergySolution\\ApiBundle\\Entity\\DataSource, but is an instance of class Doctrine\\Common\\Collections\\ArrayCollection. You can avoid this error by setting the \"data_class\" option to null or by adding a view transformer that transforms an instance of class Doctrine\\Common\\Collections\\ArrayCollection to an instance of EnergySolution\\ApiBundle\\Entity\\DataSource.""
Почему мой вариант с несколькими вариантами не работает?
Редактировать добавить сопоставление:
$table = $builder->getClassMetadata()->getTableName();
$builder
->setTable('chart_energy_goal')
->createField('name', Type::STRING)
->nullable()
->build()
->createField('title1', Type::STRING)
->nullable()
->build()
->createManyToOne('dsRef1', DataSource::class)
->cascadeAll()
->build()
->createManyToMany('dsList1', DataSource::class)
->setJoinTable("{$table}_dsList1")
->addJoinColumn("{$table}_id", 'id')
->build()
->createField('goal1', Type::FLOAT)
->build()
->createField('title2', Type::STRING)
->nullable()
->build()
->createManyToOne('dsRef2', DataSource::class)
->cascadeAll()
->build()
->createManyToMany('dsList2', DataSource::class)
->setJoinTable("{$table}_dsList2")
->addJoinColumn("{$table}_id", 'id')
->build()
->createField('goal2', Type::FLOAT)
->build()
->createField('title3', Type::STRING)
->nullable()
->build()
->createManyToOne('dsRef3', DataSource::class)
->cascadeAll()
->build()
->createManyToMany('dsList3', DataSource::class)
->setJoinTable("{$table}_dsList3")
->addJoinColumn("{$table}_id", 'id')
->build()
->createField('goal3', Type::FLOAT)
->build()
;
DataSource :: class
$builder = new ClassMetadataBuilder($metadata);
$builder
->setTable('data_sources')
->setCustomRepositoryClass(EntityRepository::class)
->createField('id', Type::INTEGER)
->columnName('id')
->makePrimaryKey()
->generatedValue()
->build()
->addManyToOne('computedValue', ComputedValue::class)
->addManyToOne('probeData', ProbeData::class)
->addManyToOne('probeData', ManualData::class)
;
Редактировать решение дерьма:
После нескольких попыток я нашел свой возврат из formBuilderчто-то вроде
['computedValue' => [], 'probeData' => [], 'probeData' => []]
вместо
[dataSource ...]
Так что я преобразую данные следующим образом.
$builder->get('dsList1')
->addModelTransformer(new CallbackTransformer(
function ($dsListAsArray) {
// never edit the form
return $dsListAsArray;
},
function ($ArrayOfDataSources) {
// transform list of 'dataSource' to liste of dataSource obj.
$collection = new ArrayCollection();
$propertyAccessor = PropertyAccess::createPropertyAccessorBuilder()
->enableExceptionOnInvalidIndex()
->getPropertyAccessor()
;
foreach ($ArrayOfDataSources as $dataSourceType => $dataSourcesArray) {
foreach ($dataSourcesArray as $dataSourceArray) {
$dataSource = new DataSource();
$propertyAccessor->setValue($dataSource, $dataSourceType, $dataSourceArray);
$collection->add($dataSource);
}
}
return $collection;
}
))
;