====== Crear un CRUD con Laravel ====== [[informatica:programacion:php:frameworks:laravel|Laravel]] En esta página se pone un ejemplo sencillo de cómo crear un CRUD en Laravel para añadir (//Create//), mostrar (//Read//), actualizar (//Update//) y eliminar (//Delete//) artículos. ===== Rutas ===== Listado de rutas que necesitaremos crear en ''routes/web.php'': // Para listar todos los posts Route::get('/posts', [PostController::class, 'index']); // Para mostrar el formulario para crear un post Route::get('/posts/create', [PostController::class, 'create']); // Para guardar un nuevo post Route::post('/posts/', [PostController::class, 'store']); // Para mostrar un determinado post Route::get('/posts/{post}', [PostController::class, 'show']); // Para mostrar el formulario de edición de un post Route::get('/posts/{post}/edit', [PostController::class, 'edit']) // Para actualizar un post Route::put('/posts/{post}', [PostController::class, 'update']) // Para eliminar un post Route::delete('/posts/{post}', [PostController::class, 'destroy']) ==== Abreviando rutas ==== Si hemos seguido ciertas convenciones en el nombre de los archivos, Laravel nos permitirá crear todas las rutas que vimos antes de una manera muy rápida: Route::resource('posts', PostController::class); Laravel supone que el controlador ''PostController.php'' tiene los siguientes métodos típicos de un CRUD: * ''index'' * ''create'' * ''store'' * ''show'' * ''edit'' * ''destroy'' Y creará por nosotros las 7 rutas necesarias. Para comprobarlo, podemos ejecutar el siguiente comando que listará las rutas definidas en nuestro proyecto de Laravel: php artisan route:list La salida debe ser la misma que cuando definimos las rutas por separado. Si quisiéramos que no se creasen todas las rutas: Route::resource('posts', PostController::class) ->except(['destroy', 'edit']); El código anterior creará todas las rutas menos las de ''destroy'' (eliminación de registros) y ''edit'' (modificar registros). También podemos hacer lo contrario, es decir, especificar las rutas que sí queremos que se creen: Route::resource('posts', PostController::class) ->only(['index', 'create', 'store']); Así solo se crearán las rutas ''index'', ''create'' y ''store''. ===== Modelo ===== Creamos un modelo para gestionar los posts: php artisan make:model Post Esto habrá creado el modelo ''Post.php'' en app/Models/: namespace App\Models; use Illuminate\Database\Eloquent\Model; class Post extends Model { } ===== Controlador ===== Creamos un controlador para los posts: php artisan make:controller PostController --create El argumento ''%%--create%%'' hace que se generen los métodos típicos para un CRUD: ''index'' (listar), ''create'', ''store'' (guardar), ''edit'', ''update'' (modificar) y ''destroy'' (eliminar). Se habrá creado un fichero ''PostController.php'' dentro de ''app/Http/Controllers'' con el siguiente contenido: ===== Vistas ===== Vista para listar los posts: php artisan make:view posts.index Vista para mostrar un post: php artisan make:view posts.show Vista para crear un post: php artisan make:view posts.create Vista para mostrar editar un post: php artisan make:view posts.edit Las vistas se crearán en ''resources/views/posts''. ===== Operaciones ===== ==== Listar posts ==== Controlador ''PostController.php'', centrándonos en el listado de posts: namespace App\Http\Controllers; use App\Models\Post; class PostController extends Controller { public function index() { $posts = Post:all(); return view('posts.index', ["posts" => $posts]); // return view('posts.index', compact('posts')); } Vista para listar los posts: php artisan make:view posts.index Creará un fichero ''index.blade.php'' en ''resources/views/posts/''

Listado de posts

==== Mostrar un post ==== Controlador ''PostController.php'', centrándonos en mostrar un post en concreto: namespace App\Http\Controllers; use App\Models\Post; class PostController extends Controller { public function show($post) { // Buscamos el registro a partir de la ID $post = Post::find($post); return view('posts.index', ["post" => $post]); // return view('posts.index', compact('post')); } Vista para mostrar un post: php artisan make:view show.index Creará un fichero ''show.blade.php'' en ''resources/views/posts/'':

Título: {{ $post->title }}

Categoría: {{ $post->category }}

{{ $post->content }}

Editar post

@csrf @method('DELETE')
==== Crear un post ==== Controlador ''PostController.php'', centrándonos en la creación de un post: namespace App\Http\Controllers; use App\Models\Post; class PostController extends Controller { public function create() { return view('posts.create') } Vista para crear un post: php artisan make:view create.index Creará un fichero ''create.blade.php'' en ''resources/views/posts/'':

Formulario para crear un nuevo post

@csrf

Por seguridad, en el envío de los formularios con Laravel es necesario incluir un //token//. De lo contrario, nos daría un error ''419''. Creamos una nueva ruta para la recepción del formulario, en ''web.php'': Route::post('/posts/', [PostController::class, 'store']); Vamos a ''PostController.php'' y definimos el método ''store()'': // .. public function store(Request $request) { $post = new Post(); $post->title = $request->title; $post->category = $request->category; $post->content = $request->content; $post->save(); // Redirigimos al listado de posts return redirect('/posts'); } ==== Editar un post ==== Crearemos dos nuevas rutas en ''routes/web.php'': Route::get('/posts/{post}/edit', [PostController::class, 'edit']) Route::put('/posts/{post}', [PostController::class, 'update']) Controlador ''PostController.php'', centrándonos en la edición de un post: namespace App\Http\Controllers; use App\Models\Post; class PostController extends Controller { public function edit($post) { $post = Post::find($post); return view('posts.edit', compact('post')) } Vista para editar un post: php artisan make:view edit.index Creará un fichero ''edit.blade.php'' en ''resources/views/posts/'':

Formulario para crear un nuevo post

@csrf @method('PUT')

Controlador ''PostController.php'', centrándonos en la actualización de un post: namespace App\Http\Controllers; use App\Models\Post; class PostController extends Controller { public function update(Request $request, $post) { //return "Aquí se actualizará el post {$post} $post = Post::find($post); $post->title = $request->title; $post->category = $request->category; $post->content = $request->content; $post->save(); return redirect("/posts/{$post->id}"); } ==== Eliminar un post ==== Creamos una nueva ruta en ''routes/web.php'': Route::delete('/posts/{post}', [PostController::class, 'destroy']) En la vista de muestra de un post, añadimos un botón para eliminar:

Título: {{ $post->title }}

Categoría: {{ $post->category }}

{{ $post->content }}

Editar post

@csrf @method('DELETE')
Controlador ''PostController.php'', centrándonos en la eliminación de un post: namespace App\Http\Controllers; use App\Models\Post; class PostController extends Controller { public function destroy($post) { //return "Eliminando el post {$post}" $post = Post::find($post); $post->delete(); return redirect("/posts"); }