Introducir datos por medio de un formulario en laravel

Vamos a comenzar a crear un CRUD en nuestra aplicación introduciendo datos a través de un formulario en Laravel, para ello hay que seguir una serie de pasos que vamos a ver en esta entrada y siguiendo con los ejemplos de las entradas anteriores.

Creando la página de mensajes

Para crear nuestros mensajes necesitaremos utilizar una acción controller y una vista.

Lo primero que haremos será crear dentro del directorio views una nueva carpeta a la cual llamaremos mensajes, ya que vamos a utilizar diferentes vistas para trabajar con los mensajes (crear, modificar, eliminar…)

De este modo dentro del directorio de mensajes vamos a crear un archivo, dentro de la carpeta mensajes, llamado create.blade.php que debe de tener el siguiente contenido:

@extends('layouts.app')
@section('title', 'Contact')
@section('content')
	<div class="container">
		<form class="form-horizontal">
			<fieldset>
				<div class="form-group">
					<label for="titulo" class="col-lg-2 control-label">Título</label>
					<div class="col-lg-10">
						<input type="text" class="form-control" id="titulo" placeholder="titulo">
					</div>
				</div>
				<div class="form-group">
					<label for="contenido" class="col-lg-2 control-label">Contenido</label>
					<div class="col-lg-10">
						<textarea class="form-control" rows="5" id="contenido"></textarea>
						<span class="help-block">Envia tu mensaje</span>
					</div>
				</div>
				<div class="form-group">
					<div class="col-lg-10 col-lg-offset-2">
					<button class="btn btn-default">Cancelar</button>
					<button type="submit" class="btn btn-primary">Enviar</button>
				</div>
			</fieldset>
		</form>
	</div>
@endsection

Una vez que lo tenemos hecho, no tenemos acceso a él por lo que hay que crear un enrutamiento como este en routes>>web.php

Route::get('/contacto', 'MensajesController@create');

Esto le está diciendo a Laravel que realice la acción que se encuentra en el método create del controlador MensajesController.php pero no tenemos creado este controlador, de modo que lo creamos utilizando artisan:

php artisan make:controller MensajesController --resource

En este caso utilizamos –resource para que se creen una seria de métodos con los cuales podemos trabajar más adelante.

De este modo en app>>Controllers>>MensajesControllers.php devolvemos la vista.

public function create()
{
    return view('mensajes.create');
}

De esta forma hemos creado un controlador específico para los mensajes, lo cual nos hará que la aplicación sea mucho más limpia y que tengamos las acciones de la misma de forma separada para un mejor mantenimiento de la misma.

Validando con HTTP Requests

En Laravel 5 se pueden validar los envíos usando las clase Request, si se cumplen las condiciones impuestas en esta clase el formulario se envía pero encaso contrario el usuario será redireccionado al formulario.

Para crear un Request lo que hay que hacer es desde el directorio raíz de nuestro proyecto utilizar el siguiente comando:

php artisan make:request MensajeFormRequest

Con esto se genera un archivo llamado MensajeFormRequest.php dentro de app>>Http>>Requests. 

Este archivo tiene dos métodos, authorize y rules.

En el método authorize por defecto se devuelve false, lo que significa que nadie podrá ejecutar la Request, por lo que hay que cambiarlo por true.

En el método rules, es donde se definen las reglas de validación, por lo que siguiendo con nuestro ejemplo, vamos a crear algunas reglas.

public function rules()
{
    return [
        'titulo' => 'required|min:3',
        'contenido' => 'required|min:20',
    ];
}

Con esto le estamos diciendo a Laravel que los dos campos sean requeridos y que tengan un mínimo de 3 y 20 caracteres respectivamente.

Como es normal existen una gran cantidad de reglas de validación que se pueden ver en la documentación oficial.

Instalar laravel collective

En la versión de Laravel 5 se eliminaron ciertos paquetes html, por lo que tenemos que instalar el paquete laravel collective, para ello hay que seguir los siguientes pasos:

  • En el archivo composer.json buscar la parte en la que aparece “require” y dejarlo de la siguiente forma: (la versión de php depende de tu instalación)
"require": {
    "php": "^7.1.3",
    "fideloper/proxy": "^4.0",
    "laravel/framework": "5.6.*",
    "laravel/tinker": "^1.0",
    "laravelcollective/html": "5.6.*"
},
  • en la terminal ejecutamos composer update para que se actualice Laravel.
  • Añadir un service provider que se encuentra en config>>app.php y en la sección de providers dentro de Package Service Providers introducir la siguiente línea.
Collective\Html\HtmlServiceProvider::class,
  • en el mismo archivo buscar los aliases y añadimos los siguientes:
 'Form' => Collective\Html\FormFacade::class, 
'Html' => Collective\Html\HtmlFacade::class, 

Lo que conseguimos de este modo es utilizar el paquete collective laravel html, que sirve para construir formularios.

Implementar el envío del formulario

Como ya debemos de saber, existen dos métodos principales para enviar datos, get y post.

En Laravel vamos a usar get cuando se recuperan datos, no para enviarlos, y post para cuando se envían datos desde formularios, ya que estos no quedan guardados en la caché ni en el historial, siendo más seguro.

De este modo abrimos nuestro archivo de rutas y creamos una nueva:

Route::post('contacto', 'MensajesController@store');

Que quiere decir que cuando se realice una petición post a contacto se ejecutará el método store del controlador MensajesController.

De este modo nos vamos a nuestros controlador MensajesController y le añadimos justo encima de la declaración de la clase la siguiente línea:

use App\Http\Requests\MensajeFormRequest;
class MensajesController extends Controller
...

Aquí le estamos diciendo a Laravel cual es el Request que tiene que utilizar.

Una vez hecho esto, buscamos la función store y le añadimos el siguiente return:

return $request->all()

Con esto ya  solo nos faltaría modificar nuestro formulario para poder enviar las peticiones post.

Para ello nos vamos a nuestra vista create.blade.php y modificamos la línea de apertura de formulario y le añadimos method=’post’




<form class="form-horizontal" method="post">

Le ponemos a los campos el atributo name para poder recuperar los datos, y nos quedarían de la siguiente manera:

<input type="text" class="form-control" id="titulo" placeholder="titulo" name="titulo">
<textarea class="form-control" rows="5" id="contenido" name="contenido"></textarea>

Para que Laravel envíe los formularios necesita tene run token de seguridad, este se suele introducir justo debajo de la etiqueta de apertura del formulario de la siguiente forma:

{!! csrf_field() !!}

Esto crea el token de forma oculta para el usuario.

Aplicar la validación

Hasta ahora estamos enviando el formulario, pero aun no estamos aplicando la validación para ello hay que decirle al método que tiene que utilizar el validador que necesitamos:

public function store(MensajeFormRequest $request)

Eso hace que si el formulario no cumpla con las validaciones se recargue, pero no da información, algo muy poco usable, por lo que habría que introducir justo debajo de la etiqueta de apertura del formulario el siguiente código:

@foreach ($errors->all() as $error)
	<span class="alert alert-danger">{{ $error}}</span>
@endforeach

Si queremos que Laravel rellene los campos que si cumplen con la validación de datos podemos poner en los campos el atributo:

value={{ old(‘nombre_del_campo’) }}

De esta forma aquellos campos que no devuelven error se rellenan con el contenido que el usuario ya había puesto.

El código de nuestro formulario final sería el siguiente:

@extends('layouts.app')
@section('title', 'Contact')
@section('content')
	<div class="container">
		<form class="form-horizontal" method="POST" action="{{ route('contacto') }}">
			@foreach ($errors->all() as $error)
				<p class="alert alert-danger">{{ $error}}</p><br>
			@endforeach
			{!! csrf_field() !!}
			<fieldset>
				<div class="form-group">
					<label for="titulo" class="col-lg-2 control-label">Título</label>
					<div class="col-lg-10">
						<input type="text" class="form-control" value="{{ old('titulo')}}" id="titulo" placeholder="titulo" name="titulo">
					</div>
				</div>
				<div class="form-group">
					<label for="contenido" class="col-lg-2 control-label">Contenido</label>
					<div class="col-lg-10">
						<textarea class="form-control" rows="5" id="contenido" name="contenido" value="{{ old('contenido') }}"></textarea>
						<span class="help-block">Envia tu mensaje</span>
					</div>
				</div>
				<div class="form-group">
					<div class="col-lg-10 col-lg-offset-2">
					<button class="btn btn-default">Cancelar</button>
					<button type="submit" class="btn btn-primary">Enviar</button>
				</div>
			</fieldset>
		</form>
	</div>
@endsection

Insertar los datos en la BBDD

Hasta este momento recogemos los datos y los validamos pero se pierden en la nada, debemos de guardarlos en la BBDD para poder hacer consultas y trabajar con ellos más adelante.

Para ello nos vamos a nuestro controlador, MensajesController.php e introducimos la siguiente línea encima de la declaración de la clase:

use App\Mensaje;

De esta forma le decimos a Laravel que queremos usar el modelo Mensaje.

Ahora vamos a la funcion store y la modificamos, dejándola así:

public function store(MensajeFormRequest $request)
{
    $slug = uniqid();
    $mensaje = new Mensaje(array(
        'titulo' => $request->get('titulo'), 
        'contenido' => $request->get('contenido'),
        'slug' => $slug
    ));
    $mensaje->save();
    return redirect('/contacto')->with('status', 'Su ticket ha sido creado, su id única es ' . $slug);
}

Aquí estamos creando una id única para identificar el mensaje que se basa en la hora.

Creamos un objeto $mensaje donde guardamos los campos del formulario.

Se hace una instancia al modelo $ticket y se llama al método save() para salvar los datos en la bbdd

Finalmente redireccionamos al usuario a la página de con un mensaje donde le decimos que el mensaje se ha guardado correctamente.

Finalmente para que laravel nor permita modificar las columnas tenemos que ir a la clase Mensaje y dejarla de la siguiente forma:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Mensaje extends Model
{
	protected $fillable = ['titulo', 'contenido', 'slug', 'status', 'id_usuario'];
}

Utilizando $fillable, le estamos indicando que las únicas columnas de la BBDD que pueden ser modificadas son las que aparecen en el array.

Finalmente para que aparezca el mensaje en la vista tenemos que añadir la siguiente, justo debajo de nuestro foreach de los errores:

@if (session('status'))	
    <div class="alert alert-success">
		{{ session('status') }}
    </div>
@endif

Así es como se pueden introducir datos por medio de un formulario en Laravel. Parece un proceso tedioso pero en realidad es bastante mecánico y una vez que está mecanizado se hace forma bastante rápida.