72

My first symfony2 project is a list of guests (invited in an event) stored in a database. I have

  • created the entity class Guest with all variables for them (id, name, address, phone number etc.)
  • created the schema in the mysql db
  • created a route for "adding a guest" to a twig template
  • created a formType

and finally a "createGuest" method in the Controller and everything works fine.

I can't manage to remove a guest from the database. I have read every tutorial in the web, including the official Symfony2 book; all that it says is :

Deleting an Object

Deleting an object is very similar, but requires a call to the remove() method of the entity manager:

$em->remove($product);
$em->flush();

It does not say anything more than that (even the "Update an object" section is missing documentation) on how to connect the controller deleteAction($id) with the twig template. What I want to do is to list all guests with a viewGuests action and a viewGuests twig template, having a delete icon next to every row, which you should click to delete an entry. Simple, but I cannot find any documentation and do not know where to start from.

public function deleteGuestAction($id)
    {
        $em = $this->getDoctrine()->getEntityManager();
        $guest = $em->getRepository('GuestBundle:Guest')->find($id);

        if (!$guest) {
            throw $this->createNotFoundException('No guest found for id '.$id);
        }

        $em->remove($guest);
        $em->flush();

        return $this->redirect($this->generateUrl('GuestBundle:Page:viewGuests.html.twig'));
    }
Jean-Rémy Revy
  • 5,607
  • 3
  • 39
  • 65
Radolino
  • 1,834
  • 4
  • 26
  • 48
  • Actually there is no error. I do not know how to interface the twig template. That means: you have a table that in each row a guest and some information (name, surname, phone number etc.) is displayed along with an icon. I want to click on that button and get the row deleted from the database. – Radolino Aug 04 '12 at 15:35
  • Is your Guest well loaded after the find() ? Else, try this prototype **public function deleteGuestAction(Guest $guest)** and delete your two first lines. Try also to var_dump your $guest – Jérôme Boé Aug 04 '12 at 15:41
  • Thanks for the replies. How should I send the Guest.name from the twig template to the controller ? – Radolino Aug 04 '12 at 15:54
  • 1
    Why send the name ? You did well sending id. – Jérôme Boé Aug 04 '12 at 15:55
  • This one gives me Controller "xxxxxBundle\Controller\PageController::deleteGuestAction()" requires that you provide a value for the "$id" argument (because there is no default value or because there is a non optional argument after this one). – Radolino Aug 06 '12 at 07:30

3 Answers3

97

Symfony is smart and knows how to make the find() by itself :

public function deleteGuestAction(Guest $guest)
{
    if (!$guest) {
        throw $this->createNotFoundException('No guest found');
    }

    $em = $this->getDoctrine()->getEntityManager();
    $em->remove($guest);
    $em->flush();

    return $this->redirect($this->generateUrl('GuestBundle:Page:viewGuests.html.twig'));
}

To send the id in your controller, use {{ path('your_route', {'id': guest.id}) }}

Brendan
  • 175
  • 2
  • 15
Jérôme Boé
  • 2,752
  • 4
  • 21
  • 32
  • I think I made a step further. Clicking on the delete icon of each entry gives me a link like "/deleteguest?id=4" which seems that the template sends the id of the current guest row. Unfortunately I am getting this message : "Unable to guess how to get a Doctrine instance from the request information." – Radolino Aug 05 '12 at 22:14
  • Your solution works. the /{id} tag was missing from the routing.yml file. I supposed that deleteguest?id=4 would do the job but it didn't. Finally deleteguest/4 seems fine. Thanks a lot. – Radolino Aug 06 '12 at 08:20
  • I think Symfony will throw exception on it's own when entity is not found, so the first conditional statement is not really necessary. – Slava Fomin II Oct 27 '14 at 13:35
  • 3
    This is working because the ParamConverter is turning your ID into a Guest entity behind the scenes. Without that you will still need to do the find() yourself – frak Jul 14 '15 at 16:22
  • As for symfony 2.6 the method getEntityManager in the included doctrine has been deprecated. You should update the answer to use: $em = $this->getDoctrine()->getManager(); – le0diaz Nov 10 '15 at 23:48
8

DELETE FROM ... WHERE id=...;

protected function templateRemove($id){
    $em = $this->getDoctrine()->getManager();
    $entity = $em->getRepository('XXXBundle:Templates')->findOneBy(array('id' => $id));

    if ($entity != null){
        $em->remove($entity);
        $em->flush();
    }
}
websky
  • 3,047
  • 1
  • 33
  • 31
3

From what I understand, you struggle with what to put into your template.

I'll show an example:

<ul>
    {% for guest in guests %}
    <li>{{ guest.name }} <a href="{{ path('your_delete_route_name',{'id': guest.id}) }}">[[DELETE]]</a></li>
    {% endfor %}
</ul>

Now what happens is it iterates over every object within guests (you'll have to rename this if your object collection is named otherwise!), shows the name and places the correct link. The route name might be different.

Sgoettschkes
  • 13,141
  • 5
  • 60
  • 78
  • This works for the link in the guests list, but it redirects to the deleteGuest.html.twig file... in which I do not know what to put in ! – Radolino Aug 05 '12 at 01:00
  • So your problem is the redirect? I don't know about your usage, but I'm doing something like `return $this->redirect($this->generateUrl('route_name_where_i_want_to_go'));` to redirect the user to a page. – Sgoettschkes Aug 05 '12 at 12:46
  • If I use public function deleteGuestAction($id='4') or any other id number that exists, it works successfully. It somehow does not get the id number from the template. What do I miss ? – Radolino Aug 06 '12 at 07:50
  • Attention: The code of Sgoettschkes might have no protection against CSRF attacks! – chris342423 Feb 08 '17 at 13:18