Eloquent en una aplicación real

Ya hemos visto el funcionamiento básico de Eloquent usando Tinker. En este capítulo vamos a empezar a usar Eloquent en una aplicación “real”. Voy a explicar todos los pasos, desde la creación de la migración hasta la ruta pasando por el modelo, y el controlador.

Como ejemplo crearemos una aplicación que sirva como catálogo de coches. Este buscador de coches tendrá la tabla:

  • Coches: la tabla que almacenará la información de los coches.

Y tendrá los siguientes campos:

  • id
  • nombre
  • potencia
  • cilindrada

En el capítulo de “Relaciones uno a varios” recuperaremos este ejemplo para añadir una tabla “fabricantes”. Por ahora vamos a simplificar al máximo.

Requisitos

  • Tener una instalación de Laravel con servidor de base de datos instalado y funcionando.

Crear la migración para la tabla coches

El primer paso es crear una migración con Artisan:

$ php artisan make:migration create_coches_table --create=coches

Al usar la opción --reate le estamos diciendo a Artisan que esta migración se va a usar para crear la tabla coches y nos generará ya parte del código. Todo el trabajo que nos ahorremos será siempre bienvenido.

Esto nos creará el fichero:

xxxx_xx_xx_xxxxxx_create_coches_table.php

Con este código:

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

class CreateCochesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('coches', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
        });
    }

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

La función up() es a la que vamos a llamar cuando ejecutemos la migración y deberá contener las instrucciones para crear la nueva tabla.

En este caso Artisan ya ha incluido el código para crear la tabla y añadirle el campo id (que será del tipo unsigned integer y se auto incrementará).

También creará los campos created_at y updated_at que servirán para tener un registro de cuándo se han creado y modificado las filas de la tabla. Este trabajo lo hace Laravel automáticamente.

Por otro lado tenemos el método down() que es el que se ejecutará si deshacemos la migración. En este caso este método lo que hace es borrar la tabla coches.

Y aquí añadiremos las siguientes líneas para crear los campos que faltan:

$table->string('nombre', 100);
$table->integer('potencia');
$table->integer('cilindrada');

Este código debe ir dentro del closure:

        Schema::create('coches', function (Blueprint $table) {
            $table->increments('id');
            $table->string('nombre', 100);
            $table->integer('potencia');
            $table->integer('cilindrada');
            $table->timestamps();
        });

Las tres primeras líneas crearán los campos nombre (texto de 100 de longitud), potencia (entero), cilindrada (entero).

Crear la tabla

Una vez tenemos las migraciones creadas podemos ejecutar la migración:

$ php artisan migrate
Migrated: xxxx_xx_xx_xxxxxx_create_coches_table

Como curiosidad, si ahora entras en tu administrador de bases de datos (por ejemplo phpMyAdmin) podrás ver que las dos tablas se han creado y cómo es su estructura.

Yo tengo instalado en mi equipo Homestead así que puedo entrar a través de un terminal:

$ homestead ssh
$ mysql -uhomestead -p
Enter password: 

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Y desde aquí puedo consultar la tabla que se ha creado:

mysql> use homestead;
Database changed
mysql> show tables;
+------------------------------+
| Tables_in_homestead          |
+------------------------------+
| coches                       |
+------------------------------+
1 row in set (0.00 sec)

mysql>

Y puedo ver cómo está definida:

mysql> show create table coches;
| coches | CREATE TABLE `coches` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `nombre` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `potencia` int(11) NOT NULL,
  `cilindrada` int(11) NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  `fabricante_id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `coches_fabricante_id_foreign` (`fabricante_id`),
  CONSTRAINT `coches_fabricante_id_foreign` FOREIGN KEY (`fabricante_id`) REFERENCES `fabricantes` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |

Conviene que eches un vistazo para ver cómo crear Laravel las tablas.

Crear un modelo para la tabla coches

Un modelo es una clase que usamos para acceder a una tabla. Los modelos son la pieza fundamental de Eloquent. Para crear el modelo de la tabla coches:

$ php artisan make:model Coche

Los modelos se nombran en singular porque representan un elemento de la tabla coches. Y, como es habitual, nada de acentos ni espacios.

Ahora echemos un vistazo al fichero recién creado:

app/Coches.php

con el siguiente código:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Coche extends Model
{
    //
}

Como puedes ver no tiene prácticamente nada de código. Por ahora es todo lo que necesitamos. Laravel es suficientemente inteligente como para saber que este modelo se está refiriendo a la tabla coches. Si lo hubiésemos llamado, por ejemplo Moto entonces entendería que la tabla relacionada sería motos.

Crear un controlador para el listado de coches

Ahora creamos un controlador que será el encargado de mostrarnos la página con el listado de coches:

$php artisan make:controller Coches

El fichero creado estará en:

app/Http/Controllers/Coches.php

Con el siguiente código:

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;

class Coches extends Controller
{
    //
}

Añadimos el método, por ejemplo, listado:

    public function listado()
    {
        $coches = Coche::all();
        return $coches;
    }

y sin olvidar añadir en la zona de los 'use':

use App\Coche;

y ya tenemos el esqueleto básico terminado.

El modelo Coche tiene un método llamado all() que nos devuelve una colección (un conjunto de objetos) con todos los coches encontrados.

NOTA: El método all() es muy cómodo pero normalmente no es una buena idea usarlo. Podría haber cientos o miles de registros en la tabla y estaríamos haciendo trabajar al servidor innecesariamente. Lo normal es limitar el número de registros a mostrar. Hablaremos sobre este tema en otros capítulos.

Crear la ruta

Si editamos el fichero app/Http/routes.php ya estaremos listos para ver el resultado. Debemos añadir la ruta para el controlador que acabamos de crear:

Route::get('coches', 'Coches@listado');

Ver el resultado

Para ver el resultado vamos a la página:

http://homestead.app/coches

NOTA: Yo estoy usando Homestead con la configuración “de fábrica” y por eso accedo a la aplicación a través de homestead.app. En tu caso tendrás que ir a la página que tienes configurada en tu servidor.

Podrás ver que el resultado no es, para nada, espectacular. Si ha ido todo bien nos encontraremos con un triste:

[]

Paciencia, todo ha ido bien. El problema es que no hemos creado ningún dato.

Añade datos de ejemplo

En este otro vídeo puedes ver cómo añadir datos de prueba en una tabla. Como estamos en una introducción a eloquent vamos a hacerlo de manera un poco chapucera y “a lo bruto” a través de un nuevo método. Añade este método en el contrlador Coches:

    public function meterDatos()
    {
        Coche::create([ 'nombre'=> 'Suzuki Vitara S', 'potencia' => 120, 'cilindrada' => 0 ]);
        Coche::create([ 'nombre'=> 'Nissan Micra', 'potencia' => 90, 'cilindrada' => 0 ]);
    }

Nota: datos inventados.

y crea su ruta correspondiente:

Route::get('meter-datos', 'Coches@meterDatos');

Si ahora entras en la URL:

http://homestead.app/meter-datos

verás un error (MassAssignmentException). Este error se produce porque Laravel nos está protegiendo de un posible ataque por Mass Assignment.

Para solucionarlo tenemos que editar el modelo Coche e indicar que queremos que a las columnas nombre y potencia se les puedan asignar valores con un array:

protected $fillable = [ 'nombre', 'potencia', 'cilindrada' ];

Ahora ya podemos recargar la página meter-datos y todo irá bien. Si recargas la página otra vez se añadirán los datos de nuevo. Como he dicho esta no es la forma correcta de hacerlo.

Volvamos a la página: http://homestead.app/coches.

Esta vez veremos el resultado que buscábamos:

[{"id":1,"nombre":"Suzuki Vitara S","potencia":120,"cilindrada":0,"created_at":"2016-08-29 19:05:20","updated_at":"2016-08-29 19:05:20"}, {"id":2,"nombre":"Nissan Micra","potencia":90,"cilindrada":0,"created_at":"2016-08-29 19:05:20","updated_at":"2016-08-29 19:05:20"}]

Esto queda muy feo porque hemos sacado los datos “a lo bruto” gracias a:

return $coches;

Laravel, una vez más, es suficientemente listo como para saber que tiene que mostrarnos un array en formato JSON con los datos.

Una vista para mostrar todo más elegante

Para mostrarlo de manera más elegante basta con usar una vista. Crea un fichero llamado:

resources/views/coches.blade.php

e introduce este código:


    @foreach($coches as $coche)
        
    @endforeach
{{$coche->nombre}} {{$coche->potencia}}

Y para hacer uso de esta vista modifica el método listado del controlador Coches reemplazando:

return $coches;

por:

return view('coches')->with(compact('coches'));

Si recargas la página el resultado será ahora más elegante.

Epílogo

Hemos repasado todo el proceso del uso de modelos en una aplicación más o menos real. Los siguientes pasos serán personalizar el uso de eloquent (para usar tablas que no coincidan con el nombre del modelo, usar índices diferentes, etc.). También hablaré de las relaciones (uno a uno, uno a varios, varios a varios) y veremos qué fáciles son de usar con Eloquent.

Autor:
Nivel: Principiante
Palabras clave:
Fecha publicado:
Fecha actualizado: 06-09-2016

Otros capítulos de la misma serie

Este capítulo es parte de la serie: Eloquent.

Y muchos más en preparación.

Disponible en los planes: Laravel hero