Contrôleurs REST imbriqués, fusionnées

Laravel 4 nous fournit les contrôleurs de ressource RESTful. Mais généralement j’ai rarement des ressources définies de façon linéaires, elles sont généralement imbriquées.
Pour un blog, on a : catégories (0->n) posts (0->n) commentaires
pour un site marchand, ce sera : categories (0->n) produits

Puisque qu’un « commentaire » est obligatoirement attaché à un « post », et que ce post est nécessairement dans une « catégorie » nous pouvons très bien imbriquer ces contrôleurs REST.
ce qui donnerait par exemple : GET /categorie/machines/produit/44

Merci Laravel :), il nous permet d’imbriquer très simplement des controleurs REST; voici la solution de route pour Laravel :

// route.php
Route::resource('categorie', 'CategorieController');
Route::resource('categorie.produit', 'CategorieProduitController');

Le reste est classique: utiliser php artisan en ligne de commande pour créer ces contrôleurs :

php artisan controller:make CategorieController 
php artisan controller:make CategorieProduitController

Pour test, je ne vais remplir que quelques méthodes :

<?php // app/controllers/CategorieController.php

class CategorieController extends \BaseController
{
	/**
	 * Display a listing of the resource.
	 * GEt /categorie/
	 * @return Response
	 */
	public function index()
	{
         echo Route::currentRouteName().'<br>';
	     echo "Categorie::index toutes categories ";
	}

	/**
	 * Display the specified resource.
	 * GET /categorie/{$id}
	 * @param  int  $id
	 * @return Response
	 */
	public function show($id)
	{
       // meme chose que GET /categorie/{$listId}/produit
        echo Route::currentRouteName().'<br>';
	    echo "Categorie::show la categorie : \"$id\", tous produits ";
	}

Ce contrôleur(parent) est des plus classique, il n’y a aucune distinction avec un contrôleur REST autonome.

Le contrôleur imbriqué (Produit), lui est particulier, en fait, toutes ces méthodes prennent un paramètre supplémentaire. Ce paramètre est le paramètre passé au controleur parent. Attention, ce paramètre n’est pas généré par la commande php artisan :(

<?php  // app/controllers/CategorieProduitController.php

class CategorieProduitController extends \BaseController {

	/**
	 * Display a listing of the resource.
	 * GET /categorie/{$listId}/produit
	 * @return Response
	 */
	public function index($listId)
	{
            // tous les produits de la categorie
            // meme que GET /categorie/{$listId}
        echo Route::currentRouteName().'<br>';
	    echo "index:: categorie : $listId, tous produits ";
	}

	/**
	 * Display the specified resource.
	 * @param int listId categorie
	 * @param  int  $id id du produit
	 * @return Response
	 */
	public function show($listId, $id)
	{
        echo Route::currentRouteName().'<br>';
	    echo "show:: categorie : $listId, produit id: $id";
	}

	/**
	 * Show the form for editing the specified resource.
         * @param int listId categorie
	 * @param  int  $id
	 * @return Response
	 */
	public function edit($listId, $id)
	{
        echo Route::currentRouteName().'<br>';
	    echo "edit:: categorie : $listId, produit id: $id";
	}

Nous pouvons utiliser ces 2 contrôleurs comme :

/categorie/44/
/categorie/44/produit/22
/categorie/44/produit/22/edit

 

Share Button

Vous devriez aimer...

1 Response

  1. patrick dit :

    Bien sur « $listId » n’est pas obligatoirement un id, on peut désirer une route de la forme :
    /categorie/nouveautés/produit/22, le slug est nettement recommandé pour le référencement.