Controladores
Introducción
En lugar de definir toda la lógica de gestión de solicitudes como closures en sus archivos de ruta, puede que desee organizar este comportamiento utilizando clases "controlador". Los controladores pueden agrupar la lógica de gestión de peticiones relacionadas en una única clase. Por ejemplo, una clase UserController
podría manejar todas las peticiones entrantes relacionadas con usuarios, incluyendo mostrar, crear, actualizar y borrar usuarios. Por defecto, los controladores se almacenan en el directorio app/Http/Controllers
.
Escribiendo Controladores
Controladores básicos
Para generar rápidamente un nuevo controlador, puedes ejecutar el comando make:controller
de Artisan. Por defecto, todos los controladores de su aplicación se almacenan en el directorio app/Http/Controllers
:
Veamos un ejemplo de controlador básico. Un controlador puede tener cualquier número de métodos públicos que responderán a las peticiones HTTP entrantes:
Una vez que haya escrito una clase y un método de controlador, puede definir una ruta al método del controlador de la siguiente manera:
Cuando una petición entrante coincide con la ruta URI especificada, el método show
de la clase App\Http\Controllers\UserController
será invocado y los parámetros de la ruta serán pasados al método.
Controladores de acción simple
Si una acción del controlador es particularmente compleja, puede que te resulte conveniente dedicar toda una clase de controlador a esa única acción. Para ello, puedes definir un único método __invoke
dentro del controlador:
Al registrar rutas para controladores de acción única, no es necesario especificar un método de controlador. En su lugar, puede simplemente pasar el nombre del controlador al enrutador:
Puedes generar un controlador invocable utilizando la opción --invokable
del comando Artisan make:controller
:
Middleware de controlador
También puede ser conveniente especificar el middleware en el constructor del controlador. Usando el método middleware
dentro del constructor de tu controlador, puedes asignar middleware a las acciones del controlador:
Los controladores también permiten registrar middleware utilizando un closure. Esto proporciona una manera conveniente de definir un middleware en línea para un solo controlador sin definir una clase entera de middleware:
Controladores de recursos
Si piensas en cada modelo Eloquent de tu aplicación como un "recurso", es típico realizar los mismos conjuntos de acciones contra cada recurso de tu aplicación. Por ejemplo, imagine que su aplicación contiene un modelo Photo
y un modelo Movie
. Es probable que los usuarios puedan crear, leer, actualizar o eliminar estos recursos.
Debido a este caso de uso común, el enrutamiento de recursos de Laravel asigna las rutas típicas de creación, lectura, actualización y eliminación ("CRUD") a un controlador con una sola línea de código. Para empezar, podemos utilizar la opción --resource
del comando Artisan make:controller
para crear rápidamente un controlador que gestione estas acciones:
Este comando generará un controlador en app/Http/Controllers/PhotoController.php
. El controlador contendrá un método para cada una de las operaciones de recursos disponibles. A continuación, puede registrar una ruta de recursos que apunte al controlador:
Esta única declaración de ruta crea múltiples rutas para manejar una variedad de acciones en el recurso. El controlador generado ya tendrá métodos para cada una de estas acciones. Recuerda, siempre puedes obtener una visión rápida de las rutas de tu aplicación ejecutando el comando route:list
de Artisan.
Puedes incluso registrar muchos controladores de recursos a la vez pasando un array al método resources
:
Acciones gestionadas por el controlador de recursos
GET
/photos
index
photos.index
GET
/photos/create
create
photos.create
POST
/photos
store
photos.store
GET
/photos/{photo}
show
photos.show
GET
/photos/{photo}/edit
edit
photos.edit
PUT/PATCH
/photos/{photo}
update
photos.update
DELETE
/photos/{photo}
destroy
photos.destroy
Personalización del comportamiento del modelo ausente
Normalmente, se generará una respuesta HTTP 404 si no se encuentra un modelo de recurso vinculado implícitamente. Sin embargo, puedes personalizar este comportamiento llamando al método missing
cuando definas tu ruta de recursos. El método missing
acepta un closure que será invocado si no se puede encontrar un modelo implícitamente enlazado para ninguna de las rutas del recurso:
Modelos Soft Deleted
Llamar a withTrashed
sin argumentos permitirá modelos borrados suavemente para las rutas de recursos show
, edit
, y update
. Puedes especificar un subconjunto de estas rutas pasando un array al método withTrashed
:
Especificar el modelo de recurso
Generar solicitudes de formularios
Rutas de recursos parciales
Al declarar una ruta de recursos, puede especificar un subconjunto de acciones que el controlador debe gestionar en lugar del conjunto completo de acciones predeterminadas:
Rutas de recursos para API
Al declarar rutas de recursos que serán consumidas por APIs, normalmente querrás excluir las rutas que presentan plantillas HTML como create
y edit
. Para mayor comodidad, puede utilizar el método apiResource
para excluir automáticamente estas dos rutas:
Puede registrar muchos controladores de recursos de API a la vez pasando una matriz al método apiResources
:
Para generar rápidamente un controlador de recursos API que no incluya los métodos create
o edit
, utilice el modificador --api
al ejecutar el comando make:controller
:
Recursos anidados
A veces puede ser necesario definir rutas a un recurso anidado. Por ejemplo, un recurso foto puede tener múltiples comentarios que pueden adjuntarse a la foto. Para anidar los controladores de recursos, puede utilizar la notación "punto" en su declaración de ruta:
Esta ruta registrará un recurso anidado al que se podrá acceder con URIs como las siguientes:
Determinación del alcance de los recursos anidados
Nidificación superficial
A menudo, no es del todo necesario tener tanto el ID padre como el ID hijo dentro de un URI, ya que el ID hijo ya es un identificador único. Cuando utilice identificadores únicos como claves primarias autoincrementadas para identificar sus modelos en segmentos URI, puede optar por utilizar el "anidamiento superficial":
Esta definición de ruta definirá las siguientes rutas:
GET
/photos/{photo}/comments
index
photos.comments.index
GET
/photos/{photo}/comments/create
create
photos.comments.create
POST
/photos/{photo}/comments
store
photos.comments.store
GET
/comments/{comment}
show
comments.show
GET
/comments/{comment}/edit
edit
comments.edit
PUT/PATCH
/comments/{comment}
update
comments.update
DELETE
/comments/{comment}
destroy
comments.destroy
Nombrando rutas de recursos
Por defecto, todas las acciones del controlador de recursos tienen un nombre de ruta; sin embargo, puede anular estos nombres pasando una matriz names
con los nombres de ruta que desee:
Nombrando parámetros de ruta de recursos
Por defecto, Route::resource
creará los parámetros de ruta para tus rutas de recursos basándose en la versión "singularizada" del nombre del recurso. Puedes anular esto fácilmente para cada recurso utilizando el método parameters
. El array pasado al método parameters
debe ser un array asociativo de nombres de recursos y nombres de parámetros:
El ejemplo anterior genera la siguiente URI para la ruta show
del recurso:
Alcance de las rutas de recursos
Esta ruta registrará un recurso anidado de alcance al que se podrá acceder con URIs como las siguientes:
Cuando se utiliza un enlace implícito con clave personalizada como parámetro de ruta anidado, Laravel automáticamente delimitará la consulta para recuperar el modelo anidado por su padre utilizando convenciones para adivinar el nombre de la relación en el padre. En este caso, se asumirá que el modelo Photo
tiene una relación llamada comments
(el plural del nombre del parámetro de ruta) que se puede utilizar para recuperar el modelo Comment
.
Localización de recursos URI
Por defecto, Route::resource
creará URIs de recursos usando verbos en inglés y reglas de plural. Si necesitas localizar los verbos de acción create
y edit
, puedes usar el método Route::resourceVerbs
. Esto puede hacerse al principio del método boot
dentro de la aplicación App\Providers\RouteServiceProvider
:
Complemento de los controladores de recursos
Si necesitas añadir rutas adicionales a un controlador de recursos más allá del conjunto predeterminado de rutas de recursos, debes definir esas rutas antes de tu llamada al método Route::resource
; de lo contrario, las rutas definidas por el método resource
pueden tener prioridad involuntariamente sobre tus rutas suplementarias:
Controladores de recursos Singleton
A veces, su aplicación tendrá recursos que sólo pueden tener una única instancia. Por ejemplo, el "perfil" de un usuario puede editarse o actualizarse, pero un usuario no puede tener más de un "perfil". Del mismo modo, una imagen puede tener una única "miniatura". Estos recursos se denominan "recursos singleton", lo que significa que sólo puede existir una instancia del recurso. En estos casos, puede registrar un controlador de recursos "singleton":
La definición de recurso singleton anterior registrará las siguientes rutas. Como puede ver, las rutas de "creación" no se registran para los recursos singleton, y las rutas registradas no aceptan un identificador ya que sólo puede existir una instancia del recurso:
GET
/profile
show
profile.show
GET
/profile/edit
edit
profile.edit
PUT/PATCH
/profile
update
profile.update
Los recursos Singleton también pueden anidarse dentro de un recurso estándar:
En este ejemplo, el recurso photos
recibiría todas las rutas de recursos estándar; sin embargo, el recurso thumbnail
sería un recurso singleton con las siguientes rutas:
GET
/photos/{photo}/thumbnail
show
photos.thumbnail.show
GET
/photos/{photo}/thumbnail/edit
edit
photos.thumbnail.edit
PUT/PATCH
/photos/{photo}/thumbnail
update
photos.thumbnail.update
Recursos creables Singleton
Ocasionalmente, puede que quieras definir rutas de creación y almacenamiento para un recurso singleton. Para ello, puede invocar el método creatable
al registrar la ruta del recurso singleton:
En este ejemplo, se registrarán las siguientes rutas. Como puede ver, también se registrará una ruta DELETE
para los recursos singleton creables:
GET
/photos/{photo}/thumbnail/create
create
photos.thumbnail.create
POST
/photos/{photo}/thumbnail
store
photos.thumbnail.store
GET
/photos/{photo}/thumbnail
show
photos.thumbnail.show
GET
/photos/{photo}/thumbnail/edit
edit
photos.thumbnail.edit
PUT/PATCH
/photos/{photo}/thumbnail
update
photos.thumbnail.update
DELETE
/photos/{photo}/thumbnail
destroy
photos.thumbnail.destroy
Si quieres que Laravel registre la ruta DELETE
para un recurso singleton pero no registra las rutas de creación o almacenamiento, puedes utilizar el método destroyable
:
Recursos API Singleton
El método apiSingleton
puede utilizarse para registrar un recurso singleton que será manipulado a través de una API, haciendo innecesarias las rutas create
y edit
:
Por supuesto, los recursos API singleton también pueden ser creables
, lo que registrará rutas store
y destroy
para el recurso:
Inyección de dependencia y controladores
Inyección al constructor
Inyección de Métodos
Además de la inyección de constructores, también puedes inyectar dependencias de tipo en los métodos de tu controlador. Un caso de uso común para la inyección de métodos es inyectar la instancia Illuminate\Http\Request
en los métodos de tu controlador:
Si el método del controlador también espera la entrada de un parámetro de ruta, enumere los argumentos de la ruta después de las otras dependencias. Por ejemplo, si la ruta se define así:
Aún puede escribir la sugerencia Illuminate\Http\Request
y acceder a su parámetro id
definiendo su método controlador de la siguiente manera:
Última actualización
¿Te fue útil?