web-dev-qa-db-fra.com

CRUD Laravel 4 comment lier pour détruire?

Je détruirai mon utilisateur avec un lien HTML, mais celui-ci ne semble pas générer le lien correct.

public function destroy($id)
{
    //Slet brugeren
    $e = new User($id);
    $e->destroy();

    //Log også brugeren ud
    Auth::logout();

    //redrect til forsiden
    Redirect::to("users/create");
}

À mon avis, j'appelle cela {{URL::action('UserController@destroy', array($user->id))}}

25
helloworld

Mise à jour le 21/08/2017 pour Laravel 5.x

La question concerne Laravel 4, mais je l’inclue au cas où les personnes à la recherche de réponses à Laravel 5.x se retrouveraient ici. L'assistant de formulaire (et quelques autres) n'est pas disponible à partir de 5.x . Vous devez toujours spécifier une méthode sur un formulaire si vous faites autre chose que GET ou POST. Voici le moyen actuel d'accomplir cela:

<form action="/foo/bar" method="POST">
    <input type="hidden" name="_method" value="PUT">
    <input type="hidden" name="_token" value="{{ csrf_token() }}">
    <!-- other inputs... -->
</form>

Vous pouvez également utiliser {{ method_field('PUT') }} au lieu d'écrire l'entrée _method masquée.

Voir https://laravel.com/docs/5.4/routing#form-method-spoofing

Réponse originale pour Laravel 4

Je pense que lorsque vous cliquez sur le lien, il envoie probablement une demande GET à ce noeud final. Le CRUD à Laravel fonctionne selon REST. Cela signifie qu'il attend une demande DELETE au lieu de GET.

Voici une possibilité tirée d'un tutorial de Boris Strahija.

    {{ Form::open(array('route' => array('admin.pages.destroy', $page->id), 'method' => 'delete')) }}
        <button type="submit" class="btn btn-danger btn-mini">Delete</button>
    {{ Form::close() }}

De cette façon, vous envoyez la demande dans un formulaire avec la méthode DELETE. L'article explique pourquoi un lien traditionnel ne fonctionne pas:

Vous remarquerez peut-être que le bouton Supprimer est à l'intérieur d'un formulaire. La raison en est que la méthode destroy () de notre contrôleur nécessite une requête DELETE, ce qui peut être fait de cette manière. Si le bouton était un simple lien, la demande serait envoyée via la méthode GET et nous n’appellerions pas la méthode destroy ().

33
Tayler

Une solution cool ajax qui fonctionne est la suivante:

function deleteUser(id) {
    if (confirm('Delete this user?')) {
        $.ajax({
            type: "DELETE",
            url: 'users/' + id, //resource
            success: function(affectedRows) {
                //if something was deleted, we redirect the user to the users page, and automatically the user that he deleted will disappear
                if (affectedRows > 0) window.location = 'users';
            }
        });
    }
}

<a href="javascript:deleteUser('{{ $user->id }}');">Delete</a>

Et dans le UserController.php, nous avons cette méthode:

public function destroy($id)
{
    $affectedRows  = User::where('id', '=', $id)->delete();

    return $affectedRows;
}

17
paulalexandru

Une autre solution "propre" consiste à utiliser le système Rails comme décrit ici :

  1. Créez un nouveau fichier .js en public et écrivez cette fonction:

    $(function(){
       $('[data-method]').append(function(){
            return "\n"+
            "<form action='"+$(this).attr('href')+"' method='POST' style='display:none'>\n"+
            "   <input type='hidden' name='_method' value='"+$(this).attr('data-method')+"'>\n"+
            "</form>\n"
       })
       .removeAttr('href')
       .attr('style','cursor:pointer;')
       .attr('onclick','$(this).find("form").submit();');
    });
    
  2. N'oubliez pas d'inclure le fichier .js dans votre modèle après avoir ajouté jQuery.

  3. Utilisez les fonctions classiques link_to() ou link_to_method() pour créer des liens permettant de supprimer des enregistrements. Rappelez-vous simplement d'inclure le paramètre "data-method"="DELETE":

    {{ link_to_route('tasks.destroy', 'D', $task->id, ['data-method'=>'delete']) }}
    

Ce qui me plaît dans cette situation, c'est que cela semble beaucoup plus propre que de gonfler votre code avec Form::open(); dans les modèles de lames.

15
user3535692

C'est une vieille question, mais je cherchais juste une réponse rapide et je ne suis satisfait d'aucune de celles-ci. Ce que je suggérerais à quiconque ayant le même problème est de créer un nouvel itinéraire. S'inquiéter trop de la conformité crud est idiot, car il n'y a rien de tel sur HTML; toutes les solutions sont adaptées aux chaussures, qu'il s'agisse d'un champ de formulaire masqué ou d'un itinéraire sécurisé.

Donc, dans vos itinéraires, vous avez probablement quelque chose comme ça:

Route::resource('users', 'UsersController'); Le problème avec ceci est que le seul moyen d'obtenir la méthode "destroy" est d'envoyer une demande de publication qui a une entrée cachée nommée "_method" et une valeur de "DELETE".

Ajoutez simplement sous cette ligne: Route::get('users/{id}/destroy',['as'=>'users.delete','uses'=>'UsersController@destroy']);

Vous avez maintenant un itinéraire auquel vous pouvez accéder à partir de HTML::linkRoute, Route::url ou de la méthode de votre choix.

Par exemple: {{ HTML::linkRoute( 'users.delete', 'Delete' , [ 'id' => $user->id ]) }}

MODIFIER

Je tiens à préciser que, même si j’ai expliqué pourquoi il est un peu ridicule de se plier en quatre pour s’adapter à la conformité crud, il est toujours vrai que votre application sera plus sécurisée si les modifications sont effectuées uniquement par le biais de demandes POST.

8
theaceofthespade

Pour ceux qui cherchent à créer le bouton de suppression dans Laravel 5:

{!! Form::open(['action' => ['UserController@destroy', $user->id], 'method' => 'delete']) !!}
  {!! Form::submit('Delete', ['class'=>'btn btn-danger btn-mini']) !!}
{!! Form::close() !!}

Ceci est similaire à la réponse de Tayler mais nous utilisons les nouvelles balises d'échappement de la lame ({!! et !!}), nous utilisons la façade Form pour générer le bouton et nous utilisons une approche plus élégante pour créer un lien vers le contrôleur. 

Dans Laravel <5, le package Formulaires & HTML a été intégré automatiquement. Dans Laravel 5, nous devons ajouter ce paquet à composer.json:

...
"required": {
  ...
  "laravelcollective/html": "^5.1"
}
...

Ajoutez maintenant le fournisseur de services et l'alias dans config/app.php:

...
'providers' => [
  ...
  Collective\Html\HtmlServiceProvider::class,
],

'aliases' => [
  ...
  'Form' => Collective\Html\FormFacade::class,
  'Html' => Collective\Html\HtmlFacade::class,
],

La sortie ci-dessus

<form method="POST" action="https://yourdomain.tld/users/1" accept-charset="UTF-8">
  <input name="_method" type="hidden" value="DELETE">
  <input name="_token" type="hidden" value="xxxCrAZyT0K3nsTr!NGxxx">
  <input class="btn btn-danger btn-mini" type="submit" value="Delete">
</form>

Si vous utilisez un générateur de formulaire différent, assurez-vous simplement qu'il génère une action similaire à celle décrite ci-dessus. 

8
DutGRIFF

Vous souhaitez envoyer une demande DELETE en dehors d'un formulaire?

Eh bien, Jeffrey Way a créé un joli javascript qui crée un formulaire pour vous et pour l'utiliser, il vous suffit d'ajouter data-method="delete" à vos liens de suppression.

Pour utiliser, importez script , et créez un lien avec l'attribut data-method="DELETE".

script:

(function() {

  var laravel = {
    initialize: function() {
      this.methodLinks = $('a[data-method]');

      this.registerEvents();
    },

    registerEvents: function() {
      this.methodLinks.on('click', this.handleMethod);
    },

    handleMethod: function(e) {
      var link = $(this);
      var httpMethod = link.data('method').toUpperCase();
      var form;

      // If the data-method attribute is not PUT or DELETE,
      // then we don't know what to do. Just ignore.
      if ( $.inArray(httpMethod, ['PUT', 'DELETE']) === - 1 ) {
        return;
      }

      // Allow user to optionally provide data-confirm="Are you sure?"
      if ( link.data('confirm') ) {
        if ( ! laravel.verifyConfirm(link) ) {
          return false;
        }
      }

      form = laravel.createForm(link);
      form.submit();

      e.preventDefault();
    },

    verifyConfirm: function(link) {
      return confirm(link.data('confirm'));
    },

    createForm: function(link) {
      var form = 
      $('<form>', {
        'method': 'POST',
        'action': link.attr('href')
      });

      var token = 
      $('<input>', {
        'type': 'hidden',
        'name': 'csrf_token',
          'value': '<?php echo csrf_token(); ?>' // hmmmm...
        });

      var hiddenInput =
      $('<input>', {
        'name': '_method',
        'type': 'hidden',
        'value': link.data('method')
      });

      return form.append(token, hiddenInput)
                 .appendTo('body');
    }
  };

  laravel.initialize();

})();
4
chebaby

Pour ceux qui cherchent à créer un bouton de suppression à l’aide de la balise anchor dans laravel 5.

{!! Form::open(['action' => ['UserController@destroy', $user->id], 'method' => 'DELETE', 'name' => 'post_' . md5($user->id . $user->created_at)]) !!}
    <a href="javascript:void(0)" title="delete" onclick="if (confirm('Are you sure?')) { document.post_<?= md5($user->id . $user->created_at) ?>.submit(); } event.returnValue = false; return false;">
        <span class="icon-remove"></span>
    </a>
{!! Form::close() !!}
2
Konsole

J'ai essayé votre code, je l'ai utilisé comme ça et j'ai travaillé:

    <a href="{{URL::action('UserController@destroy',['id'=>$user->id]) }}" 
onclick=" return confirm('Are you sure you want to delete this?')" 
class="btn btn-default">
   DELETE     </a>

Je pense que le seul problème est dans votre tableau: 

['id'=>$user->id]
1
Laura Chesches
{{Form::open(['method'=>'delete','action'=>['ResourceController@destroy',$resource->id]])}}
 <button type="submit">Delete</button>                      
{{Form::close()}}   
0
Neo