Herramientas de usuario

Herramientas del sitio


informatica:programacion:php:frameworks:laravel:crud

Crear un CRUD con 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:

<?php
 
namespace App\Http\Controllers\;
 
use Illuminate\Http\Request;
use App\Models\Post;
 
class PostController extends Controller 
{
    public function index() {}
 
    public function create() {}        
 
    public function store(Request $request) {}
 
    public function show(string $id) {}
 
    public function edit(string $id) {}        
 
    public function update(Request $request, string $id) {    }
 
    public function destroy(string $id) {    }            
 
}

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/

<h1>Listado de posts</h1>
 
<ul>
@foreach ($posts as $post) 
    <li><a href="/posts/{{$post->id}}"> {{ $post->title }}</a></li>
@endforeach
</ul>

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/:

<h1>Título: {{ $post->title }}</h1>
 
<p>Categoría: {{ $post->category }}</p>
 
<p>{{ $post->content }}</p>
 
<p><a href="/posts/{{$post->id}}/edit">Editar post</a></p>
 
<form action="/posts/{{$post->id}}" method="post">
    @csrf
    @method('DELETE')
    <button type="submit">Eliminar post</button>
</form>

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/:

<h1>Formulario para crear un nuevo post</h1>
<form action="/posts" method="post">
 
    <!-- Incluir token en un input oculto -->
    @csrf
 
    <label>Título</label>
    <input type="text" name="title">
 
    <br>
 
    <label>Categoría</label>
    <input type="text" name="category">
 
    <br>
 
    <label>Contenido</label>    
    <textarea name="content"></textarea> 
 
    <button type="submit">Crear post</button>
</form>

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/:

<h1>Formulario para crear un nuevo post</h1>
<form action="/posts/{{$post->id}}" method="post">
 
    <!-- Incluir token en un input oculto -->
    @csrf
 
    <!-- Especificamos el tipo de método a utilizar -->
    @method('PUT')
 
    <label>Título</label>
    <input type="text" name="title" value="{{ $post->title }}">
 
    <br>
 
    <label>Categoría</label>
    <input type="text" name="category" value="{{$post->category}}">
 
    <br>
 
    <label>Contenido</label>    
    <textarea name="content">{{$post->content}}</textarea> 
 
    <button type="submit">Actualizar post</button>
</form>

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:

<h1>Título: {{ $post->title }}</h1>
 
<p>Categoría: {{ $post->category }}</p>
 
<p>{{ $post->content }}</p>
 
<p><a href="/posts/{{$post->id}}/edit">Editar post</a></p>
 
<form action="/posts/{{$post->id}}" method="post">
    @csrf
    @method('DELETE')
    <button type="submit">Eliminar post</button>
</form>

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");
 
    }
informatica/programacion/php/frameworks/laravel/crud.txt · Última modificación: por tempwin