从 Symfony 中的表单集合中删除记录/学说一>多关系



尝试从嵌入在另一个表单中的表单集合中删除实体记录。我已成功将实体记录添加到同一表单集合中。

表单集合实体 (quoteItemDeliverable) 与父实体 (quoteItem) 处于 1 对 More 关系中。

使用symfony 3.3/Doctrine,并且一直在从各自的文档 https://symfony.com/doc/3.3/form/form_collections.html

使用文档,我可以删除表单元素,即集合中的项目,因为它存在于表单(树枝)中。下面的控制器代码中的 dump() 将显示这些项已从编辑窗体中的集合中删除。但是,当保留$quoteItem时,窗体中已删除的集合项不会从实体中的集合中删除(不会删除记录)。

我们正在使用的控制器代码

/**
* Edit an existing ring quote entity.
*
* @Route("/{id}/edit", name="quote-ring_edit")
* @Method({"GET", "POST"})
*/
public function editAction (Request $request, QuoteItem $quoteItem)
{
$type = $quoteItem->getCategory();
$form = $this->createForm('UniflyteBundleFormQuoteItemType', $quoteItem, ['allow_extra_fields' => true, 'attr' => ['quote-type' => 2, 'category-type' => $type]]);
$form->add('QuoteRing', QuoteRingType::class, ['label' => false]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
dump($quoteItem);
$em = $this->getDoctrine()->getManager();
$em->persist($quoteItem);
$em->flush();
//return $this->redirectToRoute('quote-ring_edit', ['id' => $quoteItem->getId()]);
}
return $this->render("quoteitem/ring.html.twig", [
'quoteItem' => $quoteItem,
'form_new'  => false,
'type'      => $type,
'form'      => $form->createView()
]);
}

集合的窗体类型如下所示

->add('quoteItemDeliverables', CollectionType::class, [
'entry_type'    => QuoteItemDeliverableType::class,
'entry_options' => array ('label' => false),
'by_reference'  => false,
'allow_add'     => true,
'allow_delete'  => true,
'prototype'     => true,
])

用于形成集合批注的 quoteItem 实体。

/**
* @ORMOneToMany(
*     targetEntity="UniflyteBundleEntityQuoteItemDeliverable",
*     mappedBy="quoteItem",
*     cascade={"persist","detach","remove"}
* )
*/
private $quoteItemDeliverables;

quoteItem 类中用于在集合中添加和删除项的方法

/**
* Add quoteItemDeliverable
*
* @param UniflyteBundleEntityQuoteItemDeliverable $quoteItemDeliverable
*
* @return QuoteItem
*/
public function addQuoteItemDeliverable (UniflyteBundleEntityQuoteItemDeliverable $quoteItemDeliverable)
{
$quoteItemDeliverable->setQuoteItem($this);
$this->quoteItemDeliverables[] = $quoteItemDeliverable;
return $this;
}
/**
* Remove quoteItemDeliverable
*
* @param UniflyteBundleEntityQuoteItemDeliverable $quoteItemDeliverable
*/
public function removeQuoteItemDeliverable (UniflyteBundleEntityQuoteItemDeliverable $quoteItemDeliverable)
{
$this->quoteItemDeliverables->removeElement($quoteItemDeliverable);
}
/**
* Get quoteItemDeliverables
*
* @return DoctrineCommonCollectionsCollection
*/
public function getQuoteItemDeliverables ()
{
return $this->quoteItemDeliverables;
}

文档指出,对于一对多,我们可能必须显式删除关系(上面提供的文档链接中的截图)。我不明白为什么。

foreach ($originalTags as $tag) {
if (false === $task->getTags()->contains($tag)) {
// remove the Task from the Tag
$tag->getTasks()->removeElement($task);
// if it was a many-to-one relationship, remove the relationship like this
// $tag->setTask(null);
$em->persist($tag);
// if you wanted to delete the Tag entirely, you can also do that
// $em->remove($tag);
}

有没有人知道我对控制器做错了什么,即转储正在正确反映,但持续删除记录的操作没有发生?

提前感谢您为应对这一挑战所付出的时间和努力。

更新- : 我遵循了 DonCallisto 的建议,并在实体级别成功从集合中删除了项目,并在控制器中使用以下操作

if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
// NOTE: Remove the quote item deliverables - will need for additional work as well?
foreach ($em->getRepository('UniflyteBundle:QuoteItemDeliverable')->findAll() as $quoteItemDeliverable) {
if (false === $quoteItem->getQuoteItemDeliverables()->contains($quoteItemDeliverable)) {
$em->remove($quoteItemDeliverable);
$em->persist($quoteItem);
}
}
$em->flush();
return $this->redirectToRoute('blah', ['id' => $quoteItem->getId()]);
}

那是因为你从关系的反转端删除了它。教义实际上只能检查拥有方的变化,所以就像你根本没有删除它一样,因为拥有方没有改变。

您需要通过EntityManager以编程方式删除该项目或将orphanRemoval设置为在注释中true(但我不推荐它! 我不建议使用orphanRemoval因为,即使它可以节省您编写更多代码,也无法将已删除的元素重新分配给其他集合(只是说让您免受将来的头痛)

此外,请确保在 from at 集合字段中有by_reference => false,否则不会调用add*remove*方法。

相关内容

  • 没有找到相关文章

最新更新