4. TAW – CRUD Laravel

4. TAW – CRUD Laravel

1.- Crear controlador y modelo para la entidad de ejemplo Productos

A diferencia de controladores anteriores, estaremos creando un controlador de tipo resource, lo cual nos permitirá tener varios métodos predefinidos para trabajar con las acciones CRUD de nuestra entidad Productos, dicho controlador se crea con el siguiente comando:

php artisan make:controller ProductosController --resource --model=Producto

La consola nos preguntara sobre el modelo así:

Respondemos con un YES y enter

Resultado de lo anterior tendremos nuestro controlador

Nuestro controlador con algunos de los métodos predefinidos.

Y nuestro modelo

Añadimos las propiedades de nuestra entidad en el modelo, y nuestro código queda de la siguiente manera:

2.- Crear la ruta para nuestra entidad productos.

En nuestro archivo de rutas web.php creamos una ruta de tipo resource y la vinculamos con el controlador ProductosController

3.- Creamos la migracion para nuestra entidad Productos.

php artisan make:migration create_productos_table --create=productos

Lo anterior da como resultado un archivo nuevo en el directorio de migraciones.

Modificaremos la función UP de la migración para añadir los campos que necesitaremos para nuestra tabla.
De esta manera quedaría nuestra migración, para que los cambios se vena reflejados en la BD ejecutaremos el siguiente comando.

php artisan migrate:refresh
Este será el resultado en nuestra base de datos.

4.- Creamos un Seeder para nuestra tabla productos.

Con el comando crearemos una nueva clase ProductosSeeder, el cual nos dará la posibilidad de generar contenido en nuestra tabla Productos, para mas adelante poder trabajar con dicha información.

php artisan make:seeder ProductosSeeder

Lo anterior dará como resultado lo siguiente:

Y modificaremos la función RUN para escribir un bucle que nos permita añadir 10 productos en nuestra tabla de BD.

Así quedaría nuestro método RUN de la clase seeder

A continuación ejecutaremos la clase ProductosSeeder desde nuestra consola siguiente comando.

php artisan db:seed --class=ProductosSeeder

Y el resultado sería el siguiente:

5.- Ver listado de productos.

Para nuestro CRUD primeramente crearemos la vista que nos permitira listar el contenido de nuestra tabla.

Primeramente crearemos un directorio dentro de view con el nombre Productos

Dentro de la carpeta produtos, creamos una plantilla sobre la cual estaremos mostrando nuestras vistas. plantilla.blade.php

La platilla en este momento solo es la estructura básica de una pagina con el CDN de bootstrap 4

Creamos nuestra primera vista index.blade.php

Extendemos nuestra vista index en la plantilla y mostramos la sección, pero aun debemos modificar nuestro controlador, para que obtenga los datos de la BD y los envíe a nuestra vista.

Modificaremos el método index de ProductosController como se muestra a continuación:

En la línea 18 estamos solicitando todos los productos, que nuestro modelo Productos reconoce de la bd, ya que al crear nuestro controlador también creamos el modelo y en dicho modelo incluimos las propiedades de nuestra entidad (cada uno de los campos de la tabla en la BD)

Ya podemos ir a nuestra ruta http://127.0.0.1:8000/productos

Este sería el resultado.

6.- Ver Detalle de un producto

Para ver el detalle de un producto, modificaremos la vista index.blade.php, para añadir un botón en la columna de acciones, el cual nos permita invocar al método SHOW de nuestro controlador y ahí obtener los detalles del producto para devolverlos a una nueva vista ( detalle.blade.php).

La linea en la imagen, es lo que añadiremos a nuestra vista index.blade.php

Con lo anterior nuestra vista quedará de la siguiente manera:

Cuando presionemos el bóton ver, estaremos enviado el id, del producto a nuestro controlador.

En el método show del controlador se modificará con lo siguiente:

Como se observa, retornaremos los datos de un producto a la vista detalle.blade.php

Vista detalle.blade.php

Aquí simplemente imprimimos dentro de un card, cada una de las propiedades del producto y al final agregamos un par de botones, de los cuales de momento solo el primero funciona y nos devolverá a la lista de productos.

Así queda la vista de detalle:

Noten como en la URL ahora muestra la misma ruta a productos y le añade el id del producto.

**Nota: en adelante podremos modificar la url de la imagen para que ya se muestre correctamente.

7.- Insertar o crear un nuevo producto.

Para realizar esto, modificaremos nuevamente el index.blade.php, para añadir un botón que nos mande a una nueva vista, en la cual tengamos un formulario y podamos ingresar la información del producto.

Esta es la modificación en la vista index.blade.php

El resultado de lo anterior se ve así:

Al dar click en el botón se modificará la ruta a esto: http://127.0.0.1:8000/productos/create, por lo tanto tendremos que crear una nueva vista que se muestre en dicha ruta, y en la cual tengamos nuestro formulario.

nuevo.blade.php

**Nota en la linea 13 hay un elemento que es necesario dentro de laravel, mas información al respecto en https://laravel.com/docs/7.x/csrf

En el siguiente bloque les dejo el código de este formulario:

@extends('productos.plantilla')

@section('content')
	<div class="card">
		<div class="card-header">
			<h3>Nuevo producto</h3>
		</div>
		<div class="card-body">
			<form action="{{ route('productos.store') }}" method="POST">
				<!-- CSRF----- Anytime you define an HTML form in your application, you should include a hidden CSRF token 
					field in the form so that the CSRF protection middleware can validate the request. You may use the @csrf 
					Blade directive to generate the token field: -->
				@csrf
				<div class="row">
					<div class="col-lg-12">
						<div class="form-group">
							<label>Nombre:</label>
							<input type="text" name="nombre" class="form-control" placeholder="Nombre del producto">
						</div>
					</div>		
					<div class="col-lg-12">
						<div class="form-group">
							<label>Descripcion:</label>
							<input type="text" name="descripcion" class="form-control" placeholder="descripcion del producto">
						</div>
					</div>		
					<div class="col-lg-12">
						<div class="form-group">
							<label>Imagen:</label>
							<input type="file" name="img_url" class="form-control" >
						</div>
					</div>		
					<div class="col-lg-12">
						<div class="form-group">
							<label>Precio:</label>
							<input type="number" name="precio" class="form-control" placeholder="precio del producto">
						</div>
					</div>		
					<div class="col-lg-12">
						<div class="form-group">
							<input type="submit" class="btn btn-primary" value="Guardar">
						</div>
					</div>		
				</div>
			</form>
		</div>
		<div class="card-footer">
			<a class="btn btn-success" href="{{ route('productos.index')}}"> Cancelar </a>
		</div>	
	</div>
@endsection
El formulario se ve de la siguiente manera

Como notaran en el código, en el formulario están definidas la propiedades action y method, la primea tiene una ruta al método store del controlador y la segunda hace referencia al metodo POST, ya que los datos del formulario se enviaran por medio dicho método de la petición HTTP.

Ahora tendremos que modificar el método store de ProductosController.php

Quedará de esta manera, y básicamente lo que hacemos es obtener todas las cabeceras de la $request y utilizando el método create, que la clase Producto heredó de la clase Model de Eloquent, insertaremos un nuevo registro en nuestra tabla de BD.

Después redirigimos al usuario a la vista productos.index de nuestro proyecto.
Así queda nuestro nuevo producto añadido.

8.- Editar producto

Para modificar la información de un producto, lo primero que haremos será modificar nuestra vista index.blade.php, para añadir un botón que nos permita mostrar un formulario con la información del producto.

Como se observa en la imagen, enviaremos el id del producto a la método edit de nuestro controlador.

Método edit de ProductosController

Recibimos la información del producto y la devolvemos a la vista (formulario) en donde realizaremos los cambios, para posteriormente actualizar en BD.

Vista actualizar.blade.php, esta vista es muy similar a la que utilizamos para añadir un producto, a continuación describo los cambios.

Se modificó el encabezado en la vista.
Se añade el id de producto en el atributo action del formulario, y se conserva el método POST.

Muy importante indicar que la esta petición se realiza por medio del método PUT del protocolo HTTP

Se añade una vista de la imagen actual, del producto, (NOTA: aun no esta funcionando, puesto que no estamos cargando imágenes todavía, solo almacenamos «rutas»)
Se añade el atributo value para cada input del formulario, en el cual se muestra muestra el valor de cada propiedad del producto.

Noten que el campo ID tiene la restricción , de modo que no podamos modificar.

En el siguiente bloque les dejo el código final de esta vista:

@extends('productos.plantilla')

@section('content')
	<div class="card">
		<div class="card-header">
			<h3>Actualizar producto</h3>
		</div>
		<div class="card-body">
			<form action="{{ route('productos.update', $producto->id) }}" method="POST">
				<!-- CSRF----- Anytime you define an HTML form in your application, you should include a hidden CSRF token 
					field in the form so that the CSRF protection middleware can validate the request. You may use the @csrf 
					Blade directive to generate the token field: -->
				@csrf
				@method('PUT')
				<div class="row">
					<div class="col-lg-12">
						<div class="form-group">
							<img class="img-thumbnail" src="uploads/{{ $producto -> img_url}}" width="150">	
						</div>
					</div>
				</div>
				
				<div class="row">
					<div class="col-lg-12">
						<div class="form-group">
							<label>ID:</label>
							<input type="text" name="id" class="form-control" placeholder="id del producto" 
							value="{{ $producto -> id }}" readonly="true">
						</div>
					</div>	
					<div class="col-lg-12">
						<div class="form-group">
							<label>Nombre:</label>
							<input type="text" name="nombre" class="form-control" placeholder="Nombre del producto" 
							value="{{ $producto -> nombre }}">
						</div>
					</div>		
					<div class="col-lg-12">
						<div class="form-group">
							<label>Descripcion:</label>
							<input type="text" name="descripcion" class="form-control" placeholder="descripcion del producto"
							value="{{ $producto -> descripcion }}">
						</div>
					</div>		
					<div class="col-lg-12">
						<div class="form-group">
							<label>Imagen:</label>
							<input type="text" name="img_url" class="form-control" 
							value="{{ $producto -> img_url }}" readonly="true">
						</div>
					</div>
					<div class="col-lg-12">
						<div class="form-group">
							<label>Imagen:</label>
							<input type="file" name="img_url" class="form-control" >
						</div>
					</div>		
					<div class="col-lg-12">
						<div class="form-group">
							<label>Precio:</label>
							<input type="number" name="precio" class="form-control" placeholder="precio del producto"
							value="{{ $producto -> precio }}">
						</div>
					</div>		
					<div class="col-lg-12">
						<div class="form-group">
							<input type="submit" class="btn btn-success" value="Guardar">
						</div>
					</div>		
				</div>
			</form>
		</div>
		<div class="card-footer">
			<a class="btn btn-danger" href="{{ route('productos.index')}}"> Cancelar </a>
		</div>	
	</div>
@endsection

Finalmente modificamos el método update de ProductosController.

Creamos los nuevos valores para nuestro producto y los asignamos a al objeto $datos, y finalmente con el método save, actualizamos los datos y redireccionamos a index.blade.php

9.- Eliminar un producto

De la misma forma que hicimos para Ver detalle de un producto y Actualizarlo, tendremos que modificar index.blade.php, para añadir la acción de eliminar.

Para tener la vista de esta manera, hice algunos cambios que describo a continuación.

Añadí el CDN de Fontawesome en plantilla.blade.php

<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" 
rel="stylesheet" 
integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" 
crossorigin="anonymous">

Modifique los botones de ver, editar y añadí el de eliminar.

Noten que el tercer botón esta dentro de un form, el cual tiene la action hacia el método destroy del controlador.
Se añade la protección CSRF y se indica el método de HTTP DELETE.

Con lo anterior ya tenemos la vista completa, ahora lo que sigue es recibir en el controlador la información del producto, y ejecutar en método correspondiente para eliminar el producto de la BD y redireccionar al listado de productos.

Método destroy de ProductosController.php

10.- Resumen rutas y métodos en ProductosController

Con el siguiente comando podemos ver el listado de rutas que tenemos en nuestra aplicación:
php artisan route:list

Esta es la lista de rutas, de acuerdo a como estuvimos trabajando:

1.- Ruta productos.index con método GET, se encarga de mostrar la tabla con el listado de productos, vista index.blade.php.

2.- Ruta productos.show con método GET, muestra el detalle de un producto en una nueva vista llamada detalle.blade.php.

3.- Ruta productos.crate con método GET, muestra la vista con el formulario (nuevo.blade.php) para ingresar la información del nuevo producto.

4.- Ruta productos.store con método POST, se encarga de guardar un nuevo producto en la tabla de BD. (Previamente tuvimos que ejecutar productos.create).

5.- Ruta productos.edit con metodo GET, muestra los datos de un producto en la vista actualizar.blade.php. Aquí hacemos los cambios para después guardarlos.

6.- Ruta productos.update con método PUT, se encarga de actualizar los datos de un producto en la BD. (Previamente tuvimos que ejecutar productos.edit)

7.- Ruta productos.destroy con metodo DELETE, se encarga de eliminar los datos de un producto en la BD.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Entrada anterior 3. TAW – Listar Contenido de la BD con Laravel (Ver Detalle de un elemento)
Entrada siguiente 5. TAW – Incluir Vue.js en Proyecto Laravel 7