提问人:Meyo GIT 提问时间:11/13/2023 最后编辑:Meyo GIT 更新时间:11/14/2023 访问量:25
Symfony 5:当从 MappedBy Side 添加时,ManyToMany 关系不持久,没有 'by_reference' => false
Symfony 5: ManyToMany Relationship Not Persisting When Added from MappedBy Side Without 'by_reference' => false
问:
上下文:
我正在开发一个 Symfony 5 应用程序,其中实体 InventaireActif
和 TypeActif
具有 ManyToMany 关系。通过Symfony表单管理这种关系时会出现一个问题。
问题:
在我的 TypeActif
表单中,当我添加 InventaireActif
实体时,除非我在表单生成器中设置了 'by_reference' => false
选项,否则它们不会持久化到数据库中。我想在不依赖此选项的情况下实现正确的行为。
实体配置:
发明Actif.php:
/**
* @ORM\ManyToMany(targetEntity=TypeActif::class, inversedBy="lesActifs")
*/
private $lesTypesActifs;
public function __construct()
{
$this->lesTypesActifs = new ArrayCollection();
// ... other initializations ...
}
/**
* @return Collection<int, TypeActif>
*/
public function getLesTypesActifs(): Collection
{
return $this->lesTypesActifs;
}
public function addLesTypesActif(TypeActif $lesTypesActif): self
{
if (!$this->lesTypesActifs->contains($lesTypesActif)) {
$this->lesTypesActifs[] = $lesTypesActif;
}
return $this;
}
public function removeLesTypesActif(TypeActif $lesTypesActif): self
{
$this->lesTypesActifs->removeElement($lesTypesActif);
return $this;
}
TypeActif.php:
/**
* @ORM\ManyToMany(targetEntity=InventaireActif::class, mappedBy="lesTypesActifs")
*/
private $lesActifs;
public function __construct()
{
$this->lesActifs = new ArrayCollection();
// ... other initializations ...
}
public function getLesActifs(): Collection
{
return $this->lesActifs;
}
public function addLesActif(InventaireActif $lesActif): self
{
if (!$this->lesActifs->contains($lesActif)) {
$this->lesActifs[] = $lesActif;
$lesActif->addLesTypesActif($this);
}
return $this;
}
public function removeLesActif(InventaireActif $lesActif): self
{
if ($this->lesActifs->removeElement($lesActif)) {
$lesActif->removeLesTypesActif($this);
}
return $this;
}
TypeActifType.php 中的表单配置:
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
// ... other fields ...
->add('lesActifs', EntityType::class, [
'required' => false,
'class' => InventaireActif::class,
'choice_label' => 'libelle',
// 'by_reference' => false,
'multiple' => true,
'query_builder' => function (InventaireActifRepository $repo) {
return $repo->lesActifsReformesSortedASC();
},
]);
}
在 TypeActifController.php 中编辑路由:
public function new(Request $request, TypeActifRepository $typeActifRepository, EntityManagerInterface $entityManager): Response
{
$typeActif = new TypeActif();
$form = $this->createForm(TypeActifType::class, $typeActif);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$typeActifRepository->add($typeActif, true);
return $this->redirectToRoute('app_type_actif_index', [], Response::HTTP_SEE_OTHER);
}
return $this->renderForm('type_actif/new.html.twig', [
'type_actif' => $typeActif,
'form' => $form,
]);
}
“by_reference”问题:
当
'by_reference' => false
未注释时,表单将完美运行,并且 ManyToMany 关系将按预期更新。但是,我想避免使用
“by_reference”=> false
。如果没有此选项,则通过TypeActif
窗体添加InventaireActif
实体不会保留更改。
尝试解决:
确保两个实体中的
添加
和删除
方法同步。审查了学说配置和注释。
预期行为:
当通过 TypeActif
表单添加 InventaireActif
实体时,应将更改保存到数据库中,而无需将 'by_reference' =>
false 设置为 false。
当前行为:
如果没有 'by_reference' => false
,则不会保留更改。不显示任何错误,日志也未显示任何异常情况。
答:
如果设置为(或省略),则 Symfony 的表单系统只需使用类的方法将选定的实体添加到指定的属性中。如果设置为 ,则改用您指定的自定义添加/删除方法。by_reference
true
ArrayCollection
by_reference
false
将实体保存到数据库时,仅保存对 ManyToMany 关系的拥有方所做的更改。代码中的拥有方是类中的属性。$lesTypesActifs
InventaireActif
在您的表单中,如果没有 ,您只会更新实体的属性,这是关系的反面,因此这就是不保存更改的原因。但是,如果添加 ,自定义添加/删除方法可确保拥有方也已更新,因此会保存更改。by_reference = false
$lesActifs
TypeActif
by_reference = false
我不确定您是否也有一个通过修改其属性来更新实体的表单,但如果您没有,您可能只需切换实体的拥有面和反向面即可摆脱:InventaireActif
$lesTypeActif
by_reference = false
class TypeActif {
/**
* @ORM\ManyToMany(targetEntity=InventaireActif::class, inversedBy="lesTypesActifs")
*/
private $lesActifs;
...
}
class InventaireActif {
/**
* @ORM\ManyToMany(targetEntity=TypeActif::class, mappedBy="lesActifs")
*/
private $lesTypesActifs;
...
}
评论
InventaireActif
by_reference
评论