php如何从Symfony2中的表单集合中删除实体?

时间:2015-07-08 06:03:18

标签: php forms symfony

在我的应用中,我有一个实体ContentEpisode。内容到剧集是 oneToMany 关系。意味着内容可能有很多集。

我使用表单集合来添加内容表单中的剧集。我完全遵循了这个文档:

http://symfony.com/doc/current/cookbook/form/form_collections.html

我已成功添加剧集,但问题是我无法从数据库中删除它们。前端中的删除按钮有效,但当我点击更新时,删除的剧集再次出现。

这是我的JavaScript代码:

var $collectionHolder;

// setup an "add a tag" link
var $addTagLink = $('<a href="#" class="add_tag_link">Add a tag</a>');
var $newLinkLi = $('<li></li>').append($addTagLink);

jQuery(document).ready(function() {
    // Get the ul that holds the collection of tags
    $collectionHolder = $('ul.collection');

    // add a delete link to all of the existing tag form li elements
    $collectionHolder.find('li').each(function() {
        addTagFormDeleteLink($(this));
    });


    // add the "add a tag" anchor and li to the tags ul
    $collectionHolder.append($newLinkLi);

    // count the current form inputs we have (e.g. 2), use that as the new
    // index when inserting a new item (e.g. 2)
    $collectionHolder.data('index', $collectionHolder.find(':input').length);

    $addTagLink.on('click', function(e) {
        // prevent the link from creating a "#" on the URL
        e.preventDefault();

        // add a new tag form (see next code block)
        addTagForm($collectionHolder, $newLinkLi);
    });

});

function addTagForm($collectionHolder, $newLinkLi) {
    // Get the data-prototype explained earlier
    var prototype = $collectionHolder.data('prototype');

    // get the new index
    var index = $collectionHolder.data('index');

    // Replace '__name__' in the prototype's HTML to
    // instead be a number based on how many items we have
    var newForm = prototype.replace(/__name__/g, index);

    // increase the index with one for the next item
    $collectionHolder.data('index', index + 1);

    // Display the form in the page in an li, before the "Add a tag" link li
    var $newFormLi = $('<li></li>').append(newForm);
    $newLinkLi.before($newFormLi);

    // add a delete link to the new form
    addTagFormDeleteLink($newFormLi);
}

function addTagFormDeleteLink($tagFormLi) {
    var $removeFormA = $('<a href="#">delete this tag</a>');
    $tagFormLi.append($removeFormA);

    $removeFormA.on('click', function(e) {
        // prevent the link from creating a "#" on the URL
        e.preventDefault();

        // remove the li for the tag form
        $tagFormLi.remove();
    });
}

更新行动:

$content = $em->find('MyAppBundle:Content', $id);

if (!$content) {
    throw $this->createNotFoundException('Unable to find Content entity.');
}

$originalEpisodes = $content->getEpisodes()->toArray();

$deleteForm = $this->createDeleteForm($id);
$editForm   = $this->createEditForm($content, $this->generateUrl('content_update', array('id' => $content->getId())), 'PUT', 'Update');


$editForm->handleRequest($request);


if ($editForm->isValid()) {

    foreach ($originalEpisodes as $episode) {

        if (false === $content->getEpisodes()->contains($episode)) {
            // remove the Task from the Tag
            $content->getEpisodes()->removeElement($episode);

            // if it was a many-to-one relationship, remove the relationship like this
            // $tag->setTask(null);

            $em->persist($episode);

            // if you wanted to delete the Tag entirely, you can also do that
            // $em->remove($tag);
        }
    }

    $em->persist($content);
    $em->flush();

    return $this->redirect($this->generateUrl('content_edit', array('id' => $id)));
}

实体:

/**
 * @var \Doctrine\Common\Collections\Collection
 * @ORM\OneToMany(targetEntity="Episode", mappedBy="content", cascade={"remove,persist"}, orphanRemoval=true)
 */
private $episodes;

public function removeEpisode(Episode $episode)
{
    //$this->episodes->removeElement($episode);

    //return $this;

    $this->episodes->remove($episode);
    $episode->setContent(null);
}

在我的控制器中,当我调试$content->getEpisodes()->contains($episode)时,我看到所有的返回都是真的而不是假的,所以我在想这是我的删除功能无法工作的唯一原因吗?

我甚至也试过这个:

Symfony2 form collection: How to remove entity from a collection?

但没有工作。请帮忙

根据请求

Episode Entity:

<?php

namespace Bbd\BongoAppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* Episode
*/
  class Episode
 {
/**
 * @var integer
 */
private $id;

/**
 * @var string
 */
private $unique_id;

/**
 * @var Content
 */
private $content;

/**
 * @var string
 */
private $number;

/**
 * @var string
 */
private $duration;

/**
 * @var string
 */
private $kaltura_id;

/**
 * @var integer
 */
private $views;

/**
 * Get id
 *
 * @return integer
 */
public function getId()
{
    return $this->id;
}

/**
 * Set content
 *
 * @param Content $content
 *
 * @return $this
 */
public function setContent(Content $content)
{
    $this->content = $content;
    return $this;
}

/**
 * Get content
 *
 * @return Content
 */
public function getContent()
{
    return $this->content;
}

/**
 * Set number
 *
 * @param string $number
 * @return $this
 */
public function setNumber($number)
{
    $this->number = $number;
    return $this;
}

/**
 * Get number
 *
 * @return string
 */
public function getNumber()
{
    return $this->number;
}

/**
 * Set duration
 *
 * @param string $duration
 * @return $this
 */
public function setDuration($duration)
{
    $this->duration = $duration;
    return $this;
}

/**
 * Get duration
 *
 * @return string
 */
public function getDuration()
{
    return $this->duration;
}

/**
 * Set kalturaId
 *
 * @param string $kalturaId
 * @return $this
 */
public function setKalturaId($kalturaId)
{
    $this->kaltura_id = $kalturaId;
    return $this;
}

/**
 * Get kalturaId
 *
 * @return string
 */
public function getKalturaId()
{
    return $this->kaltura_id;
}

/**
 * Set views
 *
 * @param integer $views
 * @return $this
 */
public function setViews($views)
{
    $this->views = $views;
    return $this;
}

/**
 * Get views
 *
 * @return integer
 */
public function getViews()
{
    return $this->views;
}

/**
 * Get sequence number
 *
 * @return integer|null
 */
public function getSequenceNumber()
{

    return  $this->getSequenceCount();

}

/**
 * Set uniqueId
 * @param string $uniqueId
 * @return $this
 */
public function setUniqueId($uniqueId)
{
    $this->unique_id = $uniqueId;
    return $this;
}

/**
 * Get uniqueId
 *
 * @param boolean $regenerate
 *
 * @return string
 */
public function getUniqueId()
{

    $content   = $this->getContent();

    $uniqueId  = '';
    $uniqueId .= $content->getContentOwner()->getSlug();
    $uniqueId .= $content->getSequence()[0];
    $uniqueId .= $this->getSequenceNumber();
    $uniqueId .= $content->getCategory()->getSlug();
    $uniqueId .= $content->getCategorySequence();

    $this->unique_id = strtoupper($uniqueId);

    return $this->unique_id;
}
/**
 * @var integer
 */
private $sequence_count;


/**
 * Set sequence_count
 *
 * @param integer $sequenceCount
 * @return Episode
 */
public function setSequenceCount($sequenceCount)
{
    $this->sequence_count = str_pad($sequenceCount, 3, '0', STR_PAD_LEFT);

    return $this;
}

/**
 * Get sequence_count
 *
 * @return integer
 */
public function getSequenceCount()
{
    return $this->sequence_count;
}
/**
 * @var string
 */
private $status;


/**
 * Set status
 *
 * @param string $status
 * @return Episode
 */
public function setStatus($status)
{
    $this->status = $status;

    return $this;
}

/**
 * Get status
 *
 * @return string
 */
public function getStatus()
{
    return $this->status;
}
/**
 * @var string
 */
private $bangla_number;


/**
 * Set bangla_number
 *
 * @param string $banglaNumber
 * @return Episode
 */
public function setBanglaNumber($banglaNumber)
{
    $this->bangla_number = $banglaNumber;

    return $this;
}

/**
 * Get bangla_number
 *
 * @return string 
 */
public function getBanglaNumber()
{
    return $this->bangla_number;
}
}

2 个答案:

答案 0 :(得分:1)

多次敲我的头后,终于找到了解决方案:

if ($editForm->isValid()) {
    foreach ($originalEpisodes as $episode) {
        if (!$content->getEpisodes()->contains($episode)) {
            // remove the Task from the Tag

            $em->remove($episode);
        }
    }

    $em->persist($content);
    $em->flush();
}

答案 1 :(得分:0)

   if ($editForm->isValid()) {
     foreach ($originalEpisodes as $episode) {
       if (false === $content->getEpisodes()->contains($episode)) {
          // remove the Task from the Tag
          $content->removeEpisode($episode);
          $em->persist($episode);
       }
     }
     $em->persist($content); 
     $em->flush();
   }