laravel

CRUD de Laravel con MySQL: administrador de canciones

CRUD de Laravel con MySQL o MariaDB

Hoy toca el turno de Laravel (un framework de PHP) para conectarse a la base de datos más popular: MySQL.

Creación de tabla dentro de MySQL con migración de Laravel

En este post voy a explicar cómo conectar Laravel con MySQL o MariaDB, comenzando por configurar la base de datos, pasando a través de las rutas, repasando el motor de plantillas de Blade y tocando un poco el tema de los mensajes flash.

Al final vamos a tener un CRUD o ABC, en donde se verán las operaciones básicas de Laravel con MySQL: insert o insertar, update o actualizar, select o seleccionar y finalmente delete o eliminar.

Aviso

Este CRUD es muy básico y perfecto para los que se inician en Laravel, no creas que no le puse estilos o cosas bonitas por pereza, sino que lo hice lo más simple posible para no confundir al principiante con cosas que no tienen que ver con el motivo principal.

Si no sabes PHP o MySQL, o quieres repasar un poco, dejo unos links que te pueden ayudar:

Descripción del proyecto

La razón por la que he escrito una serie de tutoriales de Laravel es porque el framework es un poco complicado de entender para explicar un simple CRUD con MySQL como el que hicimos con PHP puro.

Por ejemplo, para conectar Laravel con MySQL hay que configurar el archivo .env, establecer las rutas, definir las vistas y trabajar con modelos y migraciones.

Basta de presentaciones: haremos un CRUD de Laravel 5.8 (que debería funcionar perfectamente en otras versiones) con MySQL.

Si eres un principiante de Laravel igualmente puedes comenzar viendo este CRUD que traté de hacer lo más simple posible, aunque ahí están los enlaces a los otros posts por si te interesan.

Lo que vamos a hacer

Haremos un CRUD o ABC con Laravel y MySQL en donde registraremos canciones, las actualizaremos, eliminaremos y listaremos. Todo ello sin escribir una sola consulta SQL.

Recuerda que no veremos relaciones ni normalización, pues vamos a hacerlo lo más simple posible.

El código fuente está disponible en Github, por si vas no olvides seguirme.

Base de datos y tablas

La base de datos se llama canciones_laravel. El esquema se ve así:

/*
    Este esquema es por si no sabes manejar las migraciones
    Recomiendo ver database/migrations
*/create database canciones_laravel;
use canciones_laravel;
create table canciones(
    id bigint unsigned not null auto_increment,
    nombre varchar(100) not null,
    artista varchar(100) not null,
    album varchar(50) not null,
    anio int unsigned not null,
    primary key(id)
);

Recuerda que no es necesario que hagas la tabla, dejo el esquema para guiarte o como último recurso; de ahí basta con que ejecutes el comando php artisan migrate para que las migraciones se ejecuten. De hecho la única migración es esta.

Nota: no te preocupes por las inyecciones SQL, si usas el ORM de Laravel o la fachada de DB no hay problema.

Vistas con Blade

He definido una plantilla maestra y a partir de ella extiendo las demás. Pondré únicamente la maestra, pues las demás las puedes ver en el repositorio.

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>@yield("titulo")</title>
    <style>
    /*
        Poner bordes a las tablas. Tomado de:
        
    */    table {
        border-collapse: collapse;
    }
    
    table,
    th,
    td {
        border: 1px solid black;
    }
    
    th,
    td {
        padding: 5px;
    }
    </style>
</head>
<body>
    <a href="{{route('inicio')}}">Inicio</a>
    <a href="{{route('formAgregar')}}">Agregar</a>
    @yield("contenido")
    <hr>
    <p>
    CRUD de MySQL con Laravel. Creado por <a href="//parzibyte.me">parzibyte</a>
    </p>
</body>
</html>

Pongo algunos estilos, el pie que va en común y permito cambiar el título por las vistas que son extendidas.

También tengo dos enlaces que son formados de acuerdo al nombre de las rutas que existen en web.php, las cuales veremos más abajo.

Mensajes flash

Para avisar que la canción fue eliminada, creada o actualizada utilizo los mensajes flash como se verá en el controlador. En Blade los muestro comprobando si hay un mensaje con session.

@if(session("mensaje"))
<h3 style="color: blue;">{{ session("mensaje") }}</h3>
@endif

En el controlador se verá cómo se envían, pero como un adelanto diré que es con el método with.

El modelo

Solamente vamos a trabajar con un modelo, el cual se llama Cancion. Lo generé con:

php artisan make:model Cancion

Aunque igual y se podía simplemente crear un archivo dentro de la carpeta app.

Su definición queda así:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Cancion extends Model
{
    # Por defecto Laravel tomaría "cancion" así que mejor indicamos el nombre
    protected $table = "canciones";
    # No queremos que ponga updated_at ni created_at
    public $timestamps = false;
}

Parece simple pero con él vamos a realizar el CRUD, pues al extender de Model tiene todos los métodos del ORM de Laravel. El punto es que hay dos propiedades:

  • El nombre de la tabla, que no es necesario especificar pero si no lo hiciera, Laravel lo haría por mí con un nombre como “cancion”.
  • Los timestamps establecidos en false. Esto es porque no queremos llevar un registro de cuándo se actualizó o eliminó un elemento.

Nota: si quieres que lleven esos dos campos, en tu migración llama a $table->timestamps();

El controlador de las canciones

El controlador es el que se encarga de pegar la vista y el modelo. Queda así (ábrelo en el repositorio si quieres):

<?php

namespace App\Http\Controllers;

/*
    Si no sabes de dónde viene el nombre de las
    tablas y en dónde estamos confugrando las credenciales
    mira el archivo .env y database/esquema.sql

    También echa un vistazo a las migraciones
*/
# Queremos acceder a la petición HTTP
use Illuminate\Http\Request;

# También queremos al modelo Cancion
use App\Cancion;


class CancionesController extends Controller
{

    // Devolver la vista con todas las canciones
    public function index()
    {
        $canciones = Cancion::get();

        return view("inicio")
            ->with("canciones", $canciones);
    }
    

    public function agregarCancion(Request $peticion)
    {

        # Crear un modelo...
        $cancion = new Cancion;

        # Establecer propiedades leídas del formulario
        $cancion->nombre = $peticion->nombre;
        $cancion->artista = $peticion->artista;
        $cancion->album = $peticion->album;
        $cancion->anio = $peticion->anio;
       
        # Y guardar modelo ;)
        $cancion->save();
        /*
        Ahora redirige a la ruta con el nombre
        inicio (mira routes/web.php) y pásale
        un mensaje en la variable "mensaje" con
        el valor de "Canción agregada"
         */        return redirect()
            ->route('inicio')
            ->with('mensaje', 'Canción agregada');
    }

    public function guardarCambiosDeCancion(Request $peticion)
    {
        # El id para el where de SQL
        $idCancionQueSeActualiza = $peticion->idCancion;
        # Obtener modelo fresco de la base de datos
        # Buscar o fallar
        $cancion = Cancion::findOrFail($idCancionQueSeActualiza);
        # Los nuevos datos
        $cancion->nombre = $peticion->nombre;
        $cancion->artista = $peticion->artista;
        $cancion->album = $peticion->album;
        $cancion->anio = $peticion->anio;
        # Y guardamos ;)
        $cancion->save();
        
        /*
        Ahora redirige a la ruta con el nombre
        inicio (mira routes/web.php) y pásale
        un mensaje en la variable "mensaje" con
        el valor de "Canción actualizada"
         */        return redirect()
            ->route('inicio')
            ->with('mensaje', 'Canción actualizada');

    }

    public function editarCancion(Request $peticion)
    {
        $idCancion = $peticion->route("id");
        # Obtener canción por ID o fallar, es decir, mostrar un 404
        $cancion = Cancion::findOrFail($idCancion);
        return view("editar_cancion")
            ->with("cancion", $cancion);
    }

    public function eliminarCancion(Request $peticion)
    {
        # El id para el where de SQL
        $idCancionQueSeElimina = $peticion->route("id");
        # Obtener canción o mostrar 404
        $cancion = Cancion::findOrFail($idCancionQueSeElimina);
        # Eliminar
        $cancion->delete();
        /*
        Ahora redirige a la ruta con el nombre
        inicio (mira routes/web.php) y pásale
        un mensaje en la variable "mensaje" con
        el valor de "Canción eliminada"
         */        return redirect()
            ->route('inicio')
            ->with('mensaje', 'Canción eliminada');
    }
}

La cosa importante que debemos notar es que usamos el modelo para todo, y que en ningún momento estamos escribiendo una consulta SQL; todo es a través del modelo.

Para eliminar llamamos a $cancion->delete(), para guardar cambios o insertar una nueva llamamos a $cancion->save() y finalmente para obtener todas las canciones a Cancion::get();

Un método que me gusta mucho es el de findOrFail, el cual busca por id o falla; es decir, si no encuentra la canción muestra un error 404 en lugar de que intente eliminar u obtener un dato que no existe.

Antes de llamar a $cancion->save() le ponemos todos sus datos con las propiedades mágicas. Es decir, cada columna de la base de datos se representa por una propiedad. Un ejemplo es cuando le ponemos el nombre:

$cancion->nombre = $peticion->nombre;

Para obtener los datos que se enviaron por el formulario accedemos a la variable $peticion que es una instancia de Request, y Request trae de una forma cómoda lo que sea que haya sido enviado.

Finalmente en muchos casos redireccionamos a otras rutas con datos flash o flash data que muestran un mensaje de una sola vez.

Las rutas web

Ahora veamos el lugar en donde exponemos nuestra app: las rutas. Solamente fue cuestión de modificar el archivo web.php como vimos en el tutorial de rutas.

Puedes ver el archivo actualizado dentro del repositorio, y también dejo aquí el código:

<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
 */ /**
  * Recomiendo:
  * Rutas parte 1: https://parzibyte.me/blog/2019/02/14/explicando-rutas-web-laravel-5-7/
  * Rutas parte 2: https://parzibyte.me/blog/2019/02/20/rutas-laravel-parte-2-prefijos-fallback-limite-de-tasa-formularios/
  */# Cuando se solicita la url /, es decir, la raíz
Route::get('/', "CancionesController@index")
    ->name("inicio");
# Mostrar el formulario para agregar
Route::view("/agregar", "nueva_cancion")
->name("formAgregar");
# Cuando se envía el formulario y se debe guardar la canción
Route::post("/agregar", "CancionesController@agregarCancion")
    ->name("agregarCancion");
# Cuando se guardan los cambios en la base de datos
Route::post("/guardarCambios", "CancionesController@guardarCambiosDeCancion")
    ->name("guardarCambiosDeCancion");
# Mostrar el formulario para editar la canción, algo como editar/1
Route::get("/editar/{id}", "CancionesController@editarCancion")
    ->name("editarCancion");
# URL que es llamada para eliminar canción, algo como eliminar/1
Route::get("/eliminar/{id}", "CancionesController@eliminarCancion")
    ->name("eliminarCancion");

A cada ruta le pongo un nombre para luego crear un enlace en las vistas de Blade.

Poniendo todo junto

Con eso que configuramos y codificamos nuestra app ya está lista. Ahora basta con ir al sitio en donde lo tenemos alojado y podemos comenzar a probar. Aquí dejo un GIF de cómo se ve:

Demostrar CRUD de MySQL con Laravel

 

Recuerda que eres libre de descargar y probar por ti mismo el proyecto. Si tienes dudas déjalas en los comentarios.

¿Quieres aprender más de Laravel? haz click aquí.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Ver comentarios

Entradas recientes

Creador de credenciales web – Aplicación gratuita

Hoy te voy a presentar un creador de credenciales que acabo de programar y que…

1 semana hace

Desplegar PWA creada con Vue 3, Vite y SQLite3 en Apache

Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…

2 semanas hace

Arquitectura para wasm con Go, Vue 3, Pinia y Vite

En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…

2 semanas hace

Vue 3 y Vite: crear PWA (Progressive Web App)

En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…

2 semanas hace

Errores de Comlink y algunas soluciones

Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…

2 semanas hace

Esperar promesa para inicializar Store de Pinia con Vue 3

En este artículo te voy a enseñar cómo usar un "top level await" esperando a…

2 semanas hace

Esta web usa cookies.