Diario del Programador

Crear CRUD con Laravel 8 y Livewire

Image by StockSnap from Pixabay

En este tutorial aprenderás cómo crear un CRUD sencillo con Laravel 8 y Livewire. CRUD (Create, Read, Update, Delete) por sus siglas en Inglés son las cuatro funciones persistentes en una base de datos que todo sistema web debe hacer. Livewire es un framework para Laravel para el desarrollo de componentes que nos permite crear interfaces dinámicas. Al final del tutorial encontrarás el link del repositorio del proyecto. Sin más, manos a la obra.

Requisitos previos:

  1. Contar con un entorno de desarrollo como XAMPP o Laragon.
  2. Tener instalado composer de manera global en tu sistema operativo.
  3.  Node.

1. Crear un proyecto nuevo Laravel con laravel/ui

Para crear un nuevo proyecto con el instalador de Laravel abre tu terminal de comandos en la raíz de tu entorno de desarrollo y ejecuta el siguiente comando:

composer global require laravel/installer

Crea un nuevo proyecto invocando el instalador de Laravel:

laravel new laravel-livewire

Se iniciará la instalación del nuevo proyecto:

Para este proyecto usaré como sistema de autenticación laravel/ui pero tu puedes usar el sistema que mejor se adapte a las necesidades de tu proyecto. Para instalar laravel/ui ejecuta uno a uno los siguientes comandos:

composer require laravel/ui
php artisan ui bootstrap
php artisan ui bootstrap --auth
npm i
npm run watch-poll
npm install && npm run dev

2. Instalar Livewire en el proyecto Laravel

Para instalar Livewire desde la terminal de comandos escribe:

composer require livewire/livewire

Ahora tienes que agregar los assets a tu plantilla, para ello abre el archivo resources/views/layouts/app.blade.php

Antes del cierre de la etiqueta head agrega @livewireStyles

Y antes del cierre de la etiqueta body agrega @livewireScripts

3. Crear base de datos

Para crear la base de datos desde la terminal escribe lo siguiente:

mysql -u root -p

Se abrirá la consola de MySQL, ejecuta el siguiente comando:

CREATE DATABASE laravelLivewire CHARACTER SET utf8 COLLATE utf8_spanish_ci;

Para salir de la consola escribe «exit».

Ahora abre el proyecto Laravel con tu editor de textos favoritos, en mi caso usaré VS Code y en el archivo .env ingresa la información de la base de datos que acabas de crear como el nombre de la BD, el usuario y el password (si es el caso).

Para que corran las migraciones desde la terminal de comandos ejecuta la siguiente instrucción:

php artisan migrate

4. Crear modelo y migración

Para este tutorial voy a crear un modelo llamado Product con su migración,  factory y controlador, voy a simular un módulo de un sistema de inventario, para crearlo escribe en la terminal:

php artisan make:model Product -mfc

5. Editar archivo de la migración

Una vez se termine de crear los archivos desde tu editor de código dirígete a la ruta database/migrations/…x_create_products_table.php

Agrega 4 campos a la migración: ‘name’, ‘description’, ‘quantity’, ‘price’.

6. Editar archivo del Modelo Product

Abre el archivo app/Models/Product.php

Es necesario en este archivo crear una propiedad fillable con la cual Laravel permitirá realizar asignación masiva en la base de datos para ello agrega la siguiente línea de código al archivo del Modelo:

protected $fillable = ['name', 'description', 'quantity', 'price'];

7. Editar archivo ProductFactory y DatabaseSeeder

Para agregar productos de prueba a tu proyecto es necesario editar el archivo ProductFactory.php que está en la ruta database/factories/ProductFactory.php y en el método definition en el return agrega las siguientes líneas:

'name' => $this->faker->sentence(2), 
'description' => $this->faker->text(), 
'quantity' => $this->faker->randomElement([2, 4, 8, 15, 30]), 
'price' => $this->faker->numberBetween(5, 100)


Ahora ve al archivo DatabaseSeeder.php que está en la ruta database/seeders/DatabaseSeeder.php y en el método run agrega la siguiente línea que hará que 100 productos aleatorios de prueba se agreguen a la base de datos:

\App\Models\Product::factory(100)->create();

Para que se agreguen los nuevos cambios a la tabla product y se generen los productos del factory desde la terminal de comandos corre las migraciones y el seed ejecutando la instrucción:

php artisan migrate:fresh --seed

8. Crear ruta y configurar controlador

Ahora es necesario crear la ruta en el archivo route/web.php agregando la siguiente línea de código:

Route::get('/products', [ProductController::class, 'index']);

Abre el archivo App/Http/Controllers/ProductController.php y crea el método index, lo único que va a hacer este método es retornar una vista:

public function index(){         
   return view('product.index');     
}

Crea la carpeta resources/views/product y dentro de ella el archivo index.blade.php.

9. Crear componente Livewire

Para crear el componente de Livewire, ve a la terminal y escribe el siguiente comando:

php artisan make:livewire ProductComponent

Al ser el primer componente que creas, en la terminal te preguntarán si quieres destacar el repositorio en GitHub, en mi caso indique que no ya que lo he valorado anteriormente.

Se han creado dos archivos uno es la clase y el otro es la vista del componente.

Abre el archivo resoruces/views/product/index.blade.php, desde esta vista se mostrará el contenido del componente recién creado de Livewire, copia y pega el siguiente código:

@extends('layouts.app') 

@section('content') 

<div class="container">     
   @livewire('product-component') 
</div> 

@endsection

10. Lógica para mostrar registros de la base de datos

Abre el archivo de la clase de tu nuevo componente en app/Http/Livewire/ProductComponent.php, para escribir la lógica con la que se muestran los productos almacenados en la base de datos.

Vas a escribir solo unas pocas líneas de código, primero agrega el modelo Product:

use App\Models\Product;

Para la paginación vas a usar un componente integrado de Livewire:

use Livewire\WithPagination;

Y dentro de la clase padre ProductComponent vas a llamarlo:

use WithPagination;

En el método render se llaman todos los registros que se encuentran en la base de datos:

$products = Product::orderBy('id', 'desc')->paginate(10);

Y se pasan a la vista dentro de la variable ‘products’:

return view('livewire.product-component', compact('products'));

11. Vista para mostrar productos

Vas a trabajar en la vista del componente en Livewire llamada product-component.php que se encuentra en la ruta resources/views/livewire/product-component.blade.php.

Para que en esta vista se muestre los productos que se encuentran en la base de datos vas a agregar una tabla y en el tbody de la tabla vas a agregar un foreach:

<div class="row">    
  <div class="col-md-8">        
    <div class="mt-2 table-responsive-md">            
      <table class="table table-striped">                
        <thead>                  
          <tr>                    
            <th scope="col">Id</th>                    
            <th scope="col">Nombre</th>                    
            <th scope="col">Descripción</th>                    
            <th scope="col">Cantidad</th>                    
            <th scope="col">Precio</th>                    
            <th scope="col">Acción</th>                    
            <th scope="col"></th>                  
            </tr>                
        </thead>                
        <tbody>                    
          @foreach ($products as $product)                        
            <tr>                            
              <td>{{ $product->id }}</td>                            
              <td>{{ $product->name }}</td>                            
              <td>{{ $product->description }}</td>                            
              <td>{{ $product->quantity }}</td>                            
              <td>${{ $product->price }} MXN</td>                            
              <td>                                
                <button type="button" class="btn btn-success">Editar</button>                            
              </td>                            
              <td>                                
                <button type="button" class="btn btn-danger">Borrar</button>                            
              </td>                        
            </tr>                    
          @endforeach                
        </tbody>            
       </table>             
       {{ $products->links('pagination::Bootstrap-4') }}        
     </div>    
   </div>    
   <div class="col-md-4">    
   </div> 
</div>

Para ver cómo va tu proyecto desde la terminal de comandos enciende el servidor integrado de Laravel ejecutando la instrucción:

php artisan serve

Desde tu navegador ingresa a la dirección http://127.0.0.1:8000/products ya debes ver los productos que se encuentran en la base de datos listados y con paginación.

12. Borrar registros

Abre el archivo resources/views/livewire/product-component.blade.php y en donde esta la etiqueta button vas a agregar una pequeña sentencia que conectará con la clase padre del componente, cuando alguien haga click en este botón se activará el método destroy():

<button type="button" class="btn btn-danger" wire:click='destroy({{ $product->id }})'>Borrar</button>

Ahora abre el archivo de la clase del componente de Livewire en App/Http/Livewire/ProductComponent.php y vas a agregar el método destroy() el cual será el encargado de borrar el registro en la base de datos haciendo uso del id del producto que pasa desde la vista:

public function destroy($id){         
  Product::destroy($id);     
}

Ve al navegador a la dirección http://127.0.0.1:8000/products y recarga la página, si das clic al botón de borrar verás que el registro se elimina del listado.

13. Crear un nuevo producto en la base de datos

Regresa a la vista del componente en resources/views/livewire/product-component.blade.php para crear una sección en donde mostrarás un formulario para agregar nuevos productos a la base de datos. Dos líneas debajo de la paginación está la clase de boostrap col-md-4, dentro de esa clase agrega el siguiente código:

<div class="container">    
  @include("livewire.$view")
</div>

NOTA: en el include es necesario que lleve comillas dobles para que PHP lea correctamente la variable $view.

Crea el archivo resources/views/livewire/create.blade.php este archivo mostrará la vista para crear un nuevo producto, agregue el siguiente código al archivo:

<h3>Crear un nuevo producto</h3> 
  @include('livewire.form') 
  <button class="btn btn-success" wire:click='save'>
    Crear producto
  </button>

Crea el archivo resources/views/livewire/form.blade.php, en este archivo estará el formulario para crear un nuevo producto y lo reutilizarás para editar y actualizar un producto, copia y pega este código en el archivo:

<div class="form-group">
    <label>Nombre</label>
    <input type="text" class="form-control" wire:model='name'>
    @error('name') <span>{{ $message }}</span> @enderror
</div>

<div class="form-group">
    <label>Descripción</label>
    <textarea class="form-control" wire:model='description'></textarea>
    @error('description') <span>{{ $message }}</span> @enderror
</div>

<div class="form-group">
    <label>Cantidad</label>
    <input type="number" class="form-control" wire:model='quantity'>
    @error('quantity') <span>{{ $message }}</span> @enderror
</div>

<div class="form-group">
    <label>Precio</label>
    <input type="number" class="form-control" wire:model='price' step=".01">
    @error('price') <span>{{ $message }}</span> @enderror
</div>

Toca ir a la clase de tu componente Livewire en App/Http/Livewire/ProductComponent.php primero tienes que dar de alta las propiedades que tienes en el formulario para que se conecten:

public $product_id, $name, $description, $quantity, $price;

Agrega la variable $view que es con la que haremos que se visualice la vista create o edit según corresponda de manera dinámica.

public $view = 'create';

Y creas el método save() que es el que se ejecuta cuando das clic en el botón guardar del formulario:

public function save(){
       $this->validate([
           'name' => 'required',
           'description' => 'required',
           'quantity' => 'required',
           'price' => 'required'
       ]);

       Product::create([
           'name'        => $this->name,
           'description' => $this->description,
           'quantity'    => $this->quantity,
           'price'       => $this->price
       ]);
       $this->reset();
   }

Ahora si vas al navegador, actualizas la página de la aplicación y creas un nuevo producto verás que se agrega al listado de productos de la izquierda, ¡vas por el camino correcto para crear un CRUD con Laravel 8 y Livewire!

14. Editar un producto

Configura el botón Editar de tu archivo resources/views/livewire/product-component.blade.php para que se conecte al método edit() agrega lo siguiente:

<button type="button" class="btn btn-success" wire:click='edit({{ $product->id }})'>Editar</button>

Crea el método edit() en la clase de tu componente en App/Http/Livewire/ProductComponent.php 

public function edit($id){
        $product = Product::find($id);

        $this->product_id = $product->id;
        $this->name = $product->name;
        $this->description = $product->description;
        $this->quantity = $product->quantity;
        $this->price = $product->price;

        $this->view = 'edit';
    }

Si observas al final de este método estás cambiando el valor de la variable $view por el valor ‘edit’ haciendo esto las vistas create y edit se hacen dinámicas.

En el mismo archivo que estás trabajando crea el método update() que es el que se encargará de realizar las actualizaciones a la base de datos:

public function update(){
        $this->validate([
            'name' => 'required',
            'description' => 'required',
            'quantity' => 'required',
            'price' => 'required'
        ]);
        $product = Product::find($this->product_id);
        $product->update([
            'name'        => $this->name,
            'description' => $this->description,
            'quantity'    => $this->quantity,
            'price'       => $this->price
        ]);

        $this->reset();
    }

Crea el archivo resources/views/livewire/edit.blade.php y agrega las siguientes líneas:

<h3>Editar producto</h3>

    @include('livewire.form')

<button class="btn btn-primary" wire:click="update">Guardar cambios</button>

Prueba tu proyecto en el navegador, verás que cada parte de tu CRUD en Laravel 8 y Livewire están funcionando correctamente (Crear, Leer, Actualizar, Borrar).

Conclusión.

Como has visto crear un CRUD con Laravel 8 y Livewire es sumamente sencillo, existen distintas maneras para realizar este tipo de CRUD’s con la tecnología de Livewire, te he mostrado sólo una manera de hacerlo. Sí te ha servido este tutorial te invito darle una manita arriba y a compartirlo en tus redes sociales para llegar a más personas, si tienes dudas o comentarios déjalos en la caja de comentarios, estaré al pendiente de ellos. Saludos!

Repositorio GitHub del tutorial.
Cómo clonar un proyecto en Laravel
Referencias: https://laravel-livewire.com/docs/2.x/installation

Salir de la versión móvil