sonja
sonja

Reputation: 934

Delete single doctrine entry by ID in Symfony

I'm trying to set up a blog and I have a list of all blog entries as well as a list of all users for that blog. The admin of the blog has the possibility to delete single entries from these lists. Anyway, I have the problem that when selecting one entry to be deleted, it's always the first entry in my list which gets deleted and not the one I actually selected.

Here's my deleteAction:

  /**
    * @Route("/blog/delete/{id}", name="entrydelete", requirements={"id" = "\d+"}, defaults={"id" = 0})
    *
    */
    public function deleteAction(Request $request, Blog $blog) {
       $em = $this->getDoctrine()->getManager();
       $entry = $em->getRepository('BlogBundle:Blog')->find($blog);
      if ($this->get('security.authorization_checker')->isGranted('ROLE_ADMIN') || $entry->getAuthor() == $this->getUser()->getUsername() ) {
          $em->remove($entry);
          $em->flush();
          return $this->render('BlogBundle:blog:deletesubmit.html.twig');
        }
      else {
        return $this->render('BlogBundle:blog:error.html.twig');
      }
    }
    public function configureOptions(OptionsResolver $resolver) {
      $resolver->setDefaults([
        'data_class' => 'BlogBundle\Entity\Blog'
      ]);
    }

and the according twig template:

{% for blog in bloglist %}
  <h4>{{ blog.title }}</h4>
    <p><span class="fa fa-clock-o"></span> Posted on {{ blog.date|date('d.M Y H:i A') }} </p>
    <p><span class="fa fa-user-circle"></span> Posted by {{ blog.author }} </p>
    <p>{{ blog.text }}</p>

      <button type="button" class="btn btn btn-info">
        <a href="{{ path('entryedit', {'id':blog.id}) }}" style="color: #FEFEFE">Edit entry</a>
      </button>
      <button type="button" class="btn btn btn-warning">
        <a href= "#myModal" role="button" data-toggle="modal" style="color: #FEFEFE">Delete entry</a>
      </button>

        <div id="myModal" class="modal fade" role="dialog">
          <div class="modal-dialog">
            <div class="modal-content">
              <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">×</button>
                <h3 class="modal-title" id="myModalLabel">Are you sure?</h3>
              </div>
                <div class="modal-body">
                  <p>Do you really want to delete this profile?</p>
                </div>
                <div class="modal-footer">
                  <button class="btn" data-dismiss="modal">
                    Go Back
                  </button>
                  <button type="button" class="btn btn btn-warning">
                    <a href="{{ path('entrydelete', {'id':blog.id}) }}" style="color: #FEFEFE">Yes</a>
                  </button>
              </div>
            </div>
          </div>
        </div>
    <hr>
  {% endfor %}

So just to clarify this: If I have a list like that: 1. Entry 1 2. Entry 2 3. Entry 3 and I want to delete Entry 3, select that one and confirm, Entry 1 is gone.

Would be happy about any kind of help!!

Upvotes: 1

Views: 914

Answers (3)

Mert &#214;ks&#252;z
Mert &#214;ks&#252;z

Reputation: 1071

if entity manager can find a Blog object with an integer id also can find with Blog $id. point is $blog should be $id, because in routing you defined it :id

change this part:

/**
* @Route("/blog/delete/{id}", name="entrydelete", requirements={"id" = "\d+"}, defaults={"id" = 0})
*
*/ 
public function deleteAction(Request $request, Blog $blog)

to

/**
* @Route("/blog/delete/{id}", name="entrydelete", requirements={"id" = "\d+"})
*
*/
public function deleteAction(Request $request, Blog $id)

Upvotes: 0

Micha&#235;l Perrin
Micha&#235;l Perrin

Reputation: 6268

There is actually a problem with your HTML code. You render as many modals as you have elements as your modal rendering is inside the {% for %} loop.

Apart from the fact that it is not really optimized to render so many modal elements, they all have the same myModal id. When you click on the "Delete entry" button, the modal with id myModal is shown, but there are 3 of them. Your browser shows the first one, that is why it is always Entry 1 which gets deleted.

There are other things that could be fixed and optimized in your code, but to answer your question, here is a simple fix.

Change this line:

<a href= "#myModal" role="button" ...>Delete entry</a>

to:

<a href="#deleteEntryModal{{ blog.id }}" role="button" ...>Delete entry</a>

And this line:

<div id="myModal" ...>

to

<div id="deleteEntryModal{{ blog.id }}" ...>

That way, you get a unique id for each modal element, which makes your page work and HTML valid too.

As I said before, several optimizations could be made too (like using only one modal element (out of the {% for %} loop), and changing the URL to delete the element with JavaScript. But that is out of the scope of this message.

Upvotes: 0

Alessandro Minoccheri
Alessandro Minoccheri

Reputation: 35973

try to change this:

public function deleteAction(Request $request, Blog $blog) {
       $em = $this->getDoctrine()->getManager();
       $entry = $em->getRepository('BlogBundle:Blog')->find($blog);

to this:

public function deleteAction(Request $request, $id) {
       $em = $this->getDoctrine()->getManager();
       $entry = $em->getRepository('BlogBundle:Blog')->find($id);

Because you need to find your entity by the id passed into the url, you aren't passed a Blog object but an id

Upvotes: 2

Related Questions