Laravel: Listar y leer registros (parte 13)

Archivos:
- app/Http/controllers/CursoController.php
- resources/views/cursos/index.blade.php
- resources/views/layouts/plantilla.blade.php
- routes/web.php
- resources/views/cursos/show.blade.php
Listar registros
Según hemos aprendido en lecciones anteriores, podemos mostrar la colección completa de cursos si añadimos estas líneas al método index de CursoController:
$cursos = Curso::all();
return $cursos;
Para poder darle formato a estos registros, tenemos que pasarle la colección a la vista. Por lo tanto, eliminamos la segunda línea (return $cursos) y se la pasamos a la vista de la siguiente manera:
$cursos = Curso::all();
return view("cursos.index", compact('cursos'));
Ahora podemos utilizar la variable cursos en la vista. Abrimos index.blade.php, y usamos este bucle foreach escrito en «formato blade», en el que imprimiremos una lista ul de los cursos:
@section('content')
<h1>Bienvenido a la página de cursos</h1>
<ul>
@foreach ($cursos as $curso)
<li>{{$curso}}</li>
@endforeach
</ul>
@endsection
Listar parte de los registros
Vamos a mostrar sólo el nombre de cada curso, para ello en vez de {{$curso}} accedemos a la propiedad name.
@section('content')
<h1>Bienvenido a la página de cursos</h1>
<ul>
@foreach ($cursos as $curso)
<li>{{$curso->name}}</li>
@endforeach
</ul>
@endsection
Así podríamos acceder a cualquier propiedad de los cursos (id, descripción…).
Paginar registros
Hagamos el código más eficiente mostrando los resultados paginados. Para ello recuperaremos los cursos en el controlador con otro método distinto a all():
$cursos = Curso::paginate();
return view("cursos.index", compact('cursos'));
Esto mostrará sólo la primera página, y debería acceder a la url http://localhost/blog/public/cursos?page=2 para la siguiente.
Agregaremos unos controles para poder navegar entre las páginas. Añadimos lo siguiente al final de la vista:
<ul>
@foreach ($cursos as $curso)
<li>{{$curso->name}}</li>
@endforeach
</ul>
{{$cursos->links()}}
Primer uso de Tailwind
Tanto los botones de Previus y Next como los número de página tienen estilos prestablecidos que utilizan las clases de tailwind. Instalemos la librería tailwind para ver los estilos: accediento a tailwindcss.com podemos copiar este cdn y pegarlo en la plantilla que estamos usando, que anteriormente hemos llamado plantilla.blade.php:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@yield('title')</title>
<!-- favicon -->
<!-- estilos -->
<script src="https://cdn.tailwindcss.com"></script>
</head>
(...)
Con la simple adición de este fragmento de código en la plantilla, todas nuestras vistas se beneficiarán del css de tailwind, y veremos un resultado de la paginación más agradable. De momento no usamos tailwind, así que comentamos la línea.
Ajuste en las rutas
Vamos a realizar un pequeño ajuste en las rutas de nuestro proyecto.
Para comenzar, en el archivo routes/web.php, le daremos la propiedad name a la ruta. Concretamente, a la ruta «cursos/create» le daremos el nombre de «cursos.create». A las otras rutas les daremos su parámetro también, para usarlas más adelante. Esto permite cambiar la ruta con mucha facilidad. Podemos hacerlo con la ruta agrupada o con la ruta normal, a continuación pongo el código necesario para hacerlo en ambos casos:
// ruta agrupada
Route::controller(CursoController::class)->group(function(){
Route::get('cursos','index')->name('cursos.index');
Route::get('cursos/create','create')->name('cursos.create');
Route::get('cursos/{curso}','show')->name('cursos.show');
});
// ruta normal
/*
Route::get('cursos', [CursoController::class, 'index']);
Route::get('cursos/create', [CursoController::class, 'create'])->name('cursos.create');
Route::get('cursos/{curso}', [CursoController::class, 'show']);
*/
Al comienzo de la vista index.blade.php, donde estábamos haciendo la paginación, podemos hacer referencia a esta ruta de la siguiente manera:
@section('content')
<h1>Bienvenido a la página de cursos</h1>
{{-- <a href="cursos/create">Crear curso</a> --}}
<a href="{{route('cursos.create')}}">Crear curso</a>
Si quisiéramos, podríamos cambiar el nombre de la ruta sin preocuparnos de que el enlace siga apuntando a la misma ruta:
// podríamos tener la ruta que queramos, todo seguirá funcionando:
(...)
Route::get('blablabla','create')->name('cursos.create');
(...)
Una página para cada curso
Usaremos una ruta que ya teníamos para que cada elemento de la lista sea un enlace a cada página del curso. Para ello, convertiremos cada elemento de la lista en un enlace a una de nuestras rutas, a al que hemos añladido el atributo name (como hemos hecho en este mismo artículo, más arriba):
(...)
Route::get('cursos/{curso}','show')->name('cursos.show');
(...)
Dentro de la vista:
<li>
<a href="{{route('cursos.show')}}">{{$curso->name}}</a>
</li>
Pero esto nos devolverá un error, porque show necesita un parámetro. Así, tenemos que pasarle algo del registro, como puede ser el id. Veamos cómo se mostraría así:
<li>
{{route('cursos.show',$curso->id)}}
</li>
Esas son las rutas que queremos. Dejemos el código así:
@foreach ($cursos as $curso)
{{-- <li>{{$curso->name}}</li> --}}
{{-- <li>{{route('cursos.show')}}</li> --}}
{{-- <li>{{route('cursos.show', $curso->id)}}</li> --}}
<li>
<a href="{{route('cursos.show', $curso->id)}}">{{$curso->name}}</a>
</li>
@endforeach
Afinando el código
Haremos una serie de cambios en nuestro código para mejorarlo:
Cambiamos la función show de nuestro controlador. Estaba de la siguiente manera:
public function show($curso){
return view("cursos.show", compact("curso"));
}
Ahora le pasaremos la id como variable, y dentro recuperaremos el curso con esa id:
public function show($id){
$curso = Curso::find($id);
return view("cursos.show", compact("curso"));
}
Si visitamos alguno de los enlaces de la lista, ahora se mostrará el curso completo, pero con un mal formato. Vamos a la vista cursos.blade.php y mostraremos el nombre, el nombre en el título y la categoría, además de un enlace para volver a la lista de cursos:
@extends('layouts.plantilla')
@section('title', $curso->name)
@section('content')
{{-- <h1>Url con la variable <?php echo $curso?></h1> --}}
<h1>Bienvenido al curso {{$curso->name}}</h1>
<a href="{{route('cursos.index')}}">Volver a cursos</a>
<p><strong>Categoría: </strong>{{$curso->categoria}}</p>
<p><strong>Descripción: </strong>{{$curso->description}}</p>
@endsection
Recursos:
Enlace de Youtube: https://www.youtube.com/watch?v=bisZbFOB_Io&list=PLZ2ovOgdI-kWWS9aq8mfUDkJRfYib-SvF&index=17