Route avec paramètres sous Laravel, avec ou sans le route model binding

Plusieurs méthodes d'action ont besoin de recevoir un ou plusieurs paramètres pour leur indiquer ce sur quoi elles doivent travailler. Par exemple, lorsqu'une méthode d'action doit afficher les détails d'un enregistrement, elle recevra généralement l'identifiant de cet enregistrement en paramètre.

Dans cet article, je vous montre le cheminement de l'information passée en paramètre à partir d'une vue qui présente un lien qui mène à une route qui mène à un contrôleur qui mène à une autre vue. Le tout, avec ou sans le route model binding. Suivez-moi bien !

▼Publicité

Pour que, dans le contrôleur, la méthode d'action sache quel enregistrement elle doit afficher, elle recevra son identifiant en paramètre.

Ex :

Contrôleur Laravel (PHP)

public function show(int $id) : View

{

    ...

}

Pour qu'elle puisse recevoir ce paramètre, quelques étapes sont nécessaires.

Dans la vue qui liste les enregistrements, chaque enregistrement sera accompagné d'un lien qui permet d'afficher les détails. Chacun de ces liens pointera vers une route. L'identifiant de l'enregistrement fera partie de cette route.

Vue Laravel (Blade)

<a href="{{ route('produits.show', [$produit->id]) }}">

    <img src="{{ asset('medias/commun/Details.svg') }}" alt="@lang('general.details')" title="@lang('general.details')" />

</a>

La syntaxe prévoit des crochets carrés, symboles utilisés pour déclarer un tableau, afin de permettre de lister plusieurs valeurs lorsque plusieurs paramètres sont requis.

Dans la définition de la route, il faut indiquer que cette route reçoit un paramètre.

Fichier routes\web.php

Route::get('produits/{id}/details', [

    'as' => 'produits.show',

    'uses' => 'ProduitsController@show',

]);

Le premier paramètre de la définition de la route indique que cette route correspond à un URL sous la forme :

URL

http://mondomaine.com/produits/4/details

Donc, un lien <a href> passe l'identifiant en paramètre à une route nommée, qui reçoit ce paramètre et le passe à la méthode d'action qui pourra à son tour l'utiliser pour initialiser les informations à afficher dans une autre vue.

Passer un paramètre à l'aide d'une route

Injection du modèle (Route model binding)

Le travail avec le paramètre id est tout à fait fonctionnel et acceptable. Cependant, lorsque le paramètre correspond à un identifiant comme dans notre exemple, Laravel nous offre un petit raccourci intéressant.

Plutôt que de nommer le paramètre id, on peut lui donner le même nom que son modèle, tout en lettres minuscules. Par exemple, s'il s'agit de l'identifiant d'un objet de type Produit, on nommera le paramètre produit. Laravel se chargera d'injecter l'objet dans le contrôleur sans que vous ayez à écrire la requête Eloquent pour le retrouver.

Avec ou sans l'injection du modèle, le paramètre passé à la route sera un identifiant.

Vue Laravel (Blade)

<a href="{{ route('produits.show', [$produit->id]) }}">...</a>

C'est au niveau du nom du paramètre dans la définition de la route et dans le contrôleur que la transformation aura lieu.

D'abord, dans la définition de la route :

Fichier routes\web.php

Route::get('produits/{produit}/details', [

    'as' => 'produits.show',

    'uses' => 'ProduitsController@show',

]);

Puis dans le contrôleur :

Contrôleur Laravel (PHP)

/**

 * Affiche les détails d'un produit.

 *

 * @return \Illuminate\View\View

 */

public function show(Produit $produit) : View

{

    return View('produits.show', compact('produit'));

}

Pour que l'injection du modèle fonctionne, il faut que le type du paramètre soit le modèle (ex : Produit). De plus, le nom du paramètre doit être le modèle, entièrement en lettres minuscules (ex : $produit).

De cette façon, plutôt que de recevoir en paramètre seulement l'identifiant, l'objet entier qui correspond à cet identifiant sera injecté dans le contrôleur.

Passer un paramètre à l'aide d'une route avec le route model binding

Et si l'enregistrement à afficher n'existe pas ?

Lorsqu'un enregistrement est injecté grâce au route model binding et qu'il n'existe pas dans la base de données, une exception de type ModelNotFoundException sera levée, ce qui générera une erreur 404.

Pour plus d'information

« Routing - Route Model Binding ». Laravel. https://laravel.com/docs/master/routing#route-model-binding

Merci de partager ! Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInPin on PinterestShare on StumbleUponEmail this to someone
Catégories