我想爲實體創建表單,該實體包含同一實體的兩個集合,但每個集合都在一個屬性中包含具有特定值的實體。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"})
。
我今天更新了我的問題。 –