Symfony 3 - 具有相同实体的多个表单集合
我想为实体创建表单,该实体包含同一实体的两个集合,但每个集合都在一个属性中包含具有特定值的实体。Symfony 3 - 具有相同实体的多个表单集合
我的数据库表看起来像这样:
Table 1: base
| id | foo | bar |
|----|-----|-----|
Table 2: extended
| id | table_1_id | type | baz |
|----|------------|------|-----|
表1和2是在1:n的关系,因此,“基极”实体可以容纳“扩展”实体的任何量。
我已经定义的实体:
class Base {
private $id;
private $foo;
private $baz;
private $extendedCollection;
/*...*/
public function getTypeA() {
$result = new ArrayCollection();
foreach ($extendedCollection->toArray() as $item) {
if ($item->getType() == "A") {
$result->add($item);
}
}
return $result;
}
/* respective for type "B" */
public function addExtendedA(Extended $a) {
if (!$this->extendedCollection->contains($a)) {
$a
->setBase($this)
->setType("A");
$this->extendedCollection->add($a);
}
return $this;
}
/* respective for type "B" */
}
class Extended {
private $id;
private $base;
private $type;
private $baz;
/*...*/
}
最后,我也创建了两个表单类:
class BaseType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('foo')
->add('bar')
->add('typeA', CollectionType::class, array(
'entry_type' => ExtendedType::class,
'entry_options' => array(
'type' => "A"
),
'allow_add' => true,
'allow_delete' => true,
'required' => false,
'by_reference' => false
)
->add('typeB', CollectionType::class, array(
'entry_type' => ExtendedType::class,
'entry_options' => array(
'type' => "B"
),
'allow_add' => true,
'allow_delete' => true,
'required' => false,
'by_reference' => false
);
/*...*/
}
}
class ExtendedType extends AbstractType {
private $type;
public function buildForm(FormBuilderInterface $builder, array $options) {
$this->type = $options['type'];`enter code here`
$builder
->add('type', HiddenType::class, array(
'data' => $this->type
)
->add('baz');
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(array(
'data_class' => Extended::class,
'type' => ""
));
}
}
期望得到的结果如下: 当请求“基地”的实体,数据库内容被解析为一个实体,并且“扩展”实体的ArrayCollection按照集合项类型被排序为两个集合“A”和“B”,并且这两个集合都被呈现为单独的表单列表。 这工作。
当更新“基本”实体时,两个“扩展”集合应该融合到新的extendedCollection中,并且实体应该被保留。 这不起作用。
如果我手动添加了一些扩展行到数据库中,我可以呈现模板,一切都显示 - 但是,当我尝试申请通过HTML表单一些变化,一个NoSuchPropertyException
被抛出,其中有消息称。我错过了什么?我能做些什么来优化这个模型?
UPDATE 2017年9月14日 我添加了一个setter函数应用新的“扩展”类别:
class Base {
/* see above for reference code */
public function setTypeACollection(ArrayCollection $typeAExtended)
{
$this->setExtendedCollection($typeAExtended, "A");
return $this;
}
/* Respective for type "B" */
private function setExtendedCollection(ArrayCollection $newExtended, $type)
{
$newExtendedCollection = new ArrayCollection();
$extendedArray = $this->extendedCollection->toArray();
foreach ($extendedArray as $k => $v) {
if ($v->getType() == $type) {
unset($extendedArray[$k]);
} else {
$newExtendedCollection->add($v);
}
}
foreach ($newExtended->toArray() as $newExt) {
$newExt->setType($type);
$newExtendedCollection->add($item);
}
$this->extendedCollection = $newExtendedCollection;
}
}
现在,NoSuchPropertyException
走了,但一个新的问题仍然存在: 当我加载基地实体从数据库中扩展集合被应用干净,但通过HTML表单更新实体会导致以下错误,具体取决于是否有更改:
- 无更改:实体以错误的方式更新,因为所有类型“B”都变成类型“A”,因此都显示在类型“A”收集中。
- 删除类型“B”:删除的类型“B”变为类型“A”而不是被删除。
- 删除类型“A”:删除的扩展保留,另外所有类型“B”都变成类型“A”。
- 添加类型“A”:添加的扩展不是持久的,此外所有类型“B”都变成类型“A”。
- 添加一个“B”型:一个
ORMInvalidArgumentException
被抛出,该消息是A new entity was found through the relationship 'Acme\Bundle\Entity\Base#extendedCollection' that was not configured to cascade persist operations for entity: Acme\Bundle\Entity\[email protected] To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'Acme\Bundle\Entity\Extended#__toString()' to get a clue.
我Extended
类包含在引用$base
属性注释@ORM\ManyToOne(targetEntity="Acme\Bundle\Entity\Base", inversedBy="extendedCollection", cascade={"persist"})
。
表单字段从表单的底层对象/类映射而来,所以当表单组件尝试将提交的值映射到此属性时,指向Base
类中的遗漏属性typeA
。
试图解决它在你Base
类中添加setTypeA(Collection $items)
方法和手动更新根据type
您extendedCollection
财产。
我今天更新了我的问题。 –