0
votes

In my app I have one entity Content and Episode. Content to Episode is oneToMany relation. Means content may have many episodes.

I used a form collection to add episodes from content form. I exactly followed this documentation:

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

I have been able to add episodes successfully but the problem is I am not able to delete them from the database. The delete button in the frontend works, but when I click update the deleted episode shows up again.

Here is my JavaScript code:

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();
    });
}

Update action:

$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)));
}

Entity:

/**
 * @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);
}

in my controller when i debug $content->getEpisodes()->contains($episode) i see all returns are true not false, so I'm thinking is this the only reason my delete function not working??

I even tried this also :

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

but not working. please help

Episode Entity as per request:

<?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
can you post Episode entity class?Tejas Gosai
why is $editForm->handleRequest($request); commented out? Are you doing that in your custom createEditForm function (that is absent from the question description)? Maybe you could first try to follow the example more precisely if you have problems getting your customized version working... i.e. use the $editForm = $this->createForm(new TaskType(), $task); and $editForm->handleRequest($request);?ejuhjav
I commented for debuging purposeAhmad Sajid
@TejasGosai added the entityAhmad Sajid
I'm not sure if this is a problem. just give it a try. cascade={"persist", "remove"} on removeEpisode(). and where is removeEpisode() called?Tejas Gosai

2 Answers

1
votes

after banging my head so many times to the wall at last found the solution:

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();
}
0
votes
   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();
   }