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 !
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 :
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.
<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.
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 :
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.
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. Le nom du paramètre sera toujours entièrement en lettres minuscules, même si le nom du modèle est composé de deux mots. Par exemple, pour le modèle MonModele, on aura le paramètre $monmodele.
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.
<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 :
Route::get('produits/{produit}/details', [
'as' => 'produits.show',
'uses' => 'ProduitsController@show',
]);
Puis dans le contrôleur :
/**
* 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.
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.
« Routing - Route Model Binding ». Laravel. https://laravel.com/docs/master/routing#route-model-binding
▼Publicité
Site fièrement hébergé chez A2 Hosting.