Laravel

Aprender a programar no es fácil pero programar rápido y de una manera cómoda y limpia aún menos. Hay que preocuparse de pensar un modelo de datos, desarrollar una lógica para trabajar con cada tipo de dato y lograr el resultado deseado. Por ejemplo, quieres hacer un formulario o recibir datos de un usuario, tienes que leer esos datos, validar que cada dato sea correcto y además procurar que la experiencia de ese usuario sea agradable y atractiva. Por debajo de la aplicación quieres que ésta sea fácil de trabajar y que sea segura.

En ese sentido PHP como lenguaje, que es a lo que me dedico, tiene súper mala fama. Mucha gente aprendió a programar en los 90s y 2000s de manera autodidacta e intuitiva sin nociones de lo que hoy se llaman patrones de arquitectura de software. Sin embargo, para desarrollo web y otras aplicaciones existe un patrón llamado MVC o Modelo-Vista-Controlador que permite separar la lógica relacionada a la base de datos como tal de la que tiene que ver con la página web o la ventana y los cálculos que uno tiene que hacer. Si MVC no te suena a nada te recomiendo leer el enlace antes de seguir.

Pero hay otro aspecto que incluso en algunas escuelas de informática se descuida, no sé bien por qué y es el uso de herramientas externas. Se nos enseña a reutilizar código pero no se nos enseña a veces que el código a reutilizar no tiene por qué ser el nuestro y que en el mundo real es necesario utilizar herramientas que hayan resuelto problemas (por ejemplo, el mismo patrón MVC ya armado, acceder rápidamente a la base de datos o cosas más pedestres como validar un formulario o paginar unos resultados) sin tener que reinventar la rueda. Para eso hay un sin fin de herramientas para cada lenguaje y PHP hoy en día (que por lo demás ha madurado mucho) cuenta con varias de ellas. La más conocida probablemente es Laravel. Un marco de trabajo o framework en inglés que nos ayuda con todo esto. No puedo entrar en detalles pero me gustaría describir los primeros pasos a seguir con Laravel para tener una aplicación.

La documentación de Laravel es buenísima pero está completamente en inglés y uno de los problemas de los programadores latinoamericanos es que no aprenden inglés, así que saber inglés y sobre todo saber aprender por mi mismo me ha ayudado un montón a avanzar en mis tareas diarias. Cuando tengo una duda muy grande he ido a StackOverflow y frecuentemente he obtenido respuestas a mis inquietudes.

Probando Laravel

Para comenzar con Laravel tenemos dos opciones:

  1. Utilizar Homestead o Valet (OSX) como máquinas virtuales para desarrollar desde ellos. El problema es que es un poco engorroso y lo peor es que si bien no es tan complicado una vez que aprendes, es que casi todos los tutoriales, sobre todo los antiguos refieren a este método, lo que aleja a nuevos usuarios.
  2. Utilizar Laragon. En Windows tenemos acceso a esta genial herramienta que recuerda bastante a XAMPP porque cumple la misma función pero adaptada al desarrollo en PHP y especialmente con Laravel.

Lo que tenemos que hacer es:

  1. Descargar una versión de Laragon (algunas traen Apache, otras Nginx y otras herramientas como node.js)
  2. Instalar Laragon. Básicamente Next->Next->Next.
  3. Abrir Laragon (y deberías comenzar a ver un ícono de “play” verde en la barra de tareas).
  4. Clic derecho -> Quick Apps -> Laravel (crea una aplicación con su respectiva base de datos)

Con eso ya tenemos una aplicación funcionando e incluso si entramos a ella usando su nombre: http://miaplicacion.test ya deberíamos verla funcionar.

Miaplicacion.test

Luego es importante revisar la configuración:

  • config/database.php ( si creaste la aplicación con Laragon, se habrá creado una base de datos con el nombre de la misma y te recomiendo crear un usuario específico para ella)
  • config/app.php (aquí se configuran las locales, el nombre de la aplicación, etc)

Tu nuevo ayudante será la línea de comandos ya que con ella podrás crear modelos, controladores, sembradores (seeders), fábricas de objetos, trabajos automatizados (jobs), crear migraciones y ejecutarlas, etc.

El modelo

Por ejemplo, si quiero crear una clase Persona debo ingresar a la línea de comandos dentro de la carpeta de mi proyecto y digitar lo siguiente:

C:\laragon\www\miaplicacion: php artisan make:model Persona -m (la opciòn -m es para crear inmediatamente una migración).

¿Qué es una migración? Es una clase que registra la creación o modificación de la estructura de una tabla en la base de datos. Lo genial de las migraciones en los marcos de trabajo o frameworks es que al estar creados en el lenguaje de la aplicación y no en el de la base de datos, permiten utilizar un mismo modelo de datos en cualquier motor de base de datos, desde sqlite hasta Oracle. Puedes probar algo en sqlite y luego recrearlo en producción en una base MySQL o MariaDB.

Esta sería la migración del modelo Persona:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePersonasTable extends Migration
{
	/**
	 * Run the migrations.
	 *
	 * @return void
	 */
	public function up()
	{
		Schema::create('personas', function (Blueprint $table) {
			$table->bigIncrements('id');
			$table->string('name');
			$table->string('email')->unique();
			$table->string('rut')->unique();
			$table->timestamp('email_verified_at')->nullable();
			$table->string('password');
			$table->rememberToken();
			$table->timestamps();
		});
	}

	/**
	 * Reverse the migrations.
	 *
	 * @return void
	 */
	public function down()
	{
		Schema::dropIfExists('personas');
	}
}

Es Eloquent (el ORM de Laravel) el encargado de traducir eso al lenguaje del motor de base de datos que queramos usar. Por cierto, no te olvides de migrar! Se hace así:

C:\laragon\www\miaplicacion: php artisan migrate

Ojo, si sale mal no demores en volver atrás con un rollback:

C:\laragon\www\miaplicacion: php artisan migrate:rollback 

Es posible que alguna tabla quede creada y tengas que borrarla por tu cuenta. Sólo cuando tu migración funcione bien es prudente proseguir con el resto.

Los modelos propiamente dichos son algo muy curioso ya que suelen ser clases que apenas contienen código. Te doy un ejemplo con la misma Persona:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Persona extends Model
{
	//
}

Esta clase es completamente válida y su primer propósito es decirle a Eloquent “existo”. Los modelos eso sí, permiten especificar detalles, por ejemplo, las relaciones entre tablas. Por ejemplo en el ejemplo de Persona no establecimos ninguna relación pero podríamos incluso especificar relaciones inversas. Por ejemplo, si la clase Venta depende de Persona, podríamos especificar la relación en ambas clases. En el caso de Persona podríamos acceder a todas las ventas relacionadas con esa persona y viceversa (ver el objeto persona desde una venta en particular).

En Persona:

public function ventas() {
	return $this->hasMany('App\Venta');
}

En Venta:

public function persona() {
	return $this->belongsTo('App\Persona');
}

Y eso es todo!

Nota: No todos los marcos de trabajo son iguales. Si han usado Django por ejemplo, se habrán dado cuenta que allí el modelo incluye la migración. En Laravel como hemos visto, ambas cosas van separadas.

Nota2: Además de Eloquent Laravel cuenta con un constructor de consultas al que se accede con una fachada llamada DB y que permite realizar cualquier operación en la base de datos con cualquier tabla aunque no sea un objeto.

El controlador

Como sabrán o se habrán figurado, el controlador comunica al modelo (los datos vamos!) con la página web y le proporciona toda la información. Una vista no debe tener una lógica muy complicada.

Vamos a crear un controlador:

C:\laragon\www\miaplicacion: php artisan make:controller PersonaController --model=Persona

Una vez en este punto podemos, por ejemplo, mostrar todas las personas. Cómo lo haríamos?

<?php

namespace App\Http\Controllers;

use App\Persona;
use Illuminate\Http\Request;

class PersonaController extends Controller
{
/**
 * Display a listing of the resource.
 *
 * @return \Illuminate\Http\Response
 */
public function index()
{
    // Muestra una lista de todos los objetos 
	$personas = Persona::all();
	return view('persona.index')->with('personas', $personas);
}

Para nada complicado. Como ven abajo, retornamos una vista ubicada en la carpeta persona y llamada al igual que el método “index” con una colección que vamos a poder visualizar en nuestra vista llamada $personas.

La vista

Esta vez vamos a crear la vista. La vista es un archivo de plantilla HTML. Las plantillas HTML utilizan un lenguaje de marcado especial para poder utilizar fácilmente las variables que vienen de un controlador sin crear un desorden. En PHP hay varios como phpview, Twig (de Symphony, bastante útil y muy sencillo), y Laravel, que es muy suyo, utiliza su propio lenguaje de plantillas llamado Blade.
No voy a entrar en detalles respecto a cómo funciona Blade, creo que el manual de Richos lo explica en español bastante bien.

Las vistas se ubican en la carpeta /resources/views pero no se pueden crear con un comando de artisan, al menos no por defecto (en Laravel podemos crear nuestros propios comandos y bajar paquetes con composer que hagan más cosas por nosotros). Entonces vamos a la carpeta señalada y creamos otra carpeta llamada “persona” y dentro de ella creamos un archivo vacío llamado index.blade.php (es importante que sea .blade.php si no, no va a funcionar).

@extends('layouts.app')
@section('content')
<div class="container">
	@isset($personas)
	<ul>
	@foreach($personas as $persona)
		<li>{{$persona->id}}</li>
		<li>{{$persona->name}}</li>
		<li>{{$persona->email}}</li>
	@endforeach
	</ul>
	@endisset
</div>
@endsection

Y eso sería un ejemplo completo de las tres partes de nuestro MVC basado en una hipotética clase Persona.

Si aprendiste a programar, si incluso aprendiste programación orientada a objetos y patrones de arquitectura de software pero no aprendiste ninguna framework o marco de trabajo, esto te va a volar la cabeza y sobre todo te va a ahorrar un tiempo valioso. Al menos a mi, esto es lo que me está dando de comer.