Recientemente se nos creo la inquietud del trabajo repetitivo de consultar la BD cuando se inyecta un ID en una ruta o la acción de un controlador. Si eres fiel seguidor de las buenas prácticas de desarrollo de software, debes saber que existe un principio llamado DRY (Don’t Repeat Yourself), que básicamente nos alienta a reducir la repetición de información de todo los tipos.
Normalmente, en una acción de actualización, supongamos para el caso en estudio, se requiere actualizar una factura. Un definición de la ruta sería la siguiente:
Route::get(‘invoice/edit/{id}’, ‘InvoiceController@edit’);
Ahora bien, la acción del controlador podría ser codificada de la siguiente forma:
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return Response
*/
public function edit($id)
{
$invoice = invoice::findOrFail($id);
$this->authorize(‘edit’, $invoice);
return view(‘invoices.edit’)
->with(‘invoice’, $invoice);
}
Esto nos refiere, que para cada acción en particular, tenemos que inyectar el ID, luego obtener el modelo relacionado al ID proporcionado. Laravel nos provee otra forma de resolver este dilema, con el Route Model Binding que implementa un método conveniente, automáticamente podemos inyectar la instancia del modelo directamente en las rutas.
En otras palabras, en lugar de inyectar el ID de la factura, se puede inyectar la instancia del modelo Invoice que corresponde al ID dado.
Implicita
Existe la forma implícita, en la cual Laravel automáticamente resuelve el modelo Eloquent definido en las rutas o las acciones del controlador, cuyos nombres de variable sugeridos por tipo coincidan con el nombre de segmento de la ruta, por ejemplo:
Route::get('api/users/{user}', function (App\User $user) {
return $user->email;
});
Como la variable $user es declarada del tipo modelo Eloquent App\User y el nombre de la variable $user corresponde al valor de segmento URI {user}, Laravel automáticamente inyectará la instancia del modelo que tenga un ID igual al que se envía en URI. Si por algún motivo no se encuentra el ID, se lanzará un error 404.
Explicita
Para registrar la forma explicita, hay que usar el método model en la ruta y especificar la clase para el parámetro dado. Se puede definir las formas explicitas en el método boot de la clase RouteServiceProvider.
public function boot()
{
parent::boot();
Route::model(‘user’, App\User::class);
}
Ahora, definimos una ruta que contenga un parámetro llamado {user}:
Route::get(‘profile/{user}’, function (App\User $user) {
//
});
Asi, como hemos atado el parámetro {user} al model App\User, una instancia de User será inyectado a la ruta. Entonces, por ejemplo, se podría llamar la ruta profile/1, lo cual inyectará la instancia User desde la base de datos donde el ID sea 1. Al igual que la forma implícita, sino se encuentra una instancia para el ID dado, se lanzará un error HTTP 404.