尝试从嵌入在另一个表单中的表单集合中删除实体记录。我已成功将实体记录添加到同一表单集合中。
表单集合实体 (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*
方法。