Añadir datos de prueba en nuestras tablas (data seeding)

Cuando estamos desarrollando una aplicación Laravel es muy conveniente tener datos en nuestras tablas para comprobar que todo funciona correctamente.

Podemos rellenar nuestras tablas de manera manual. Esto puede estar bien para un par de registros, pero es algo tedioso y lleva tiempo.

Laravel nos permite generar datos de prueba de manera muy sencilla con los database seeders (sembradores de bases de datos). Como su nombre indica nos ayudan a “sembrar” la base de datos con registros.

Vamos a usar como ejemplo una tabla noticias que vamos a crear desde cero. En esta tabla vamos a meter datos de prueba usando con un DataSeeder, “Eloquent Database factory” y un Faker para crear los datos. Tranquilo, vamos a ir paso a paso para que no te pierdas.

Requisitos

  • Este capítulo se ha escrito usando la versión 5.3 de Laravel. Se ha usado Homestead y MySQL para los ejemplos.
  • Se asume que hay una base de datos creada y configurada.
  • Uso básico de Artisan.

Crear un seeder

El primer paso es crear un seeder a través de Artisan:

$ php artisan make:seeder NoticiasSeeder
Seeder created successfully.

Este comando creará el fichero:

database/seeds/NoticiasSeeder.php

con el siguiente código:

use Illuminate\Database\Seeder;

class NoticiasSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //
    }
}

En este “seeder” podemos crear los datos directamente con Eloquent o usando DB pero lo más recomendable es usar un model factory (en la siguiente sección explicaré qué hace un model factory).

Para crear cinco noticias nuevas con datos aleatorios debemos hacer:

    public function run()
    {
        factory(App\Noticia::class, 5)->create();
    }

Este factory no lo tenemos creado así que el siguiente paso es añadirlo a nuestro proyecto.

Crear un Model Factory

Ahora tenemos que editar el fichero:

database/factories/ModelFactory.php

Este archivo ya tiene un model factory para crear usuarios de prueba:

$factory->define(App\User::class, function (Faker\Generator $faker) {
    static $password;

    return [
        'name' => $faker->name,
        'email' => $faker->safeEmail,
        'password' => $password ?: $password = bcrypt('secret'),
        'remember_token' => str_random(10),
    ];
});

Al final del fichero podemos añadir nuestro propio factory:

$factory->define(App\Noticia::class, function (Faker\Generator $faker) {

    return [
        'titulo' => $faker->sentence,
        'autor' => $faker->name,
        'fecha_publicacion' => $faker->dateTime,
    ];
});

Este factory es el que se encarga de crear los datos para cada uno de los registros. Gracias al Faker\Generator podemos tener datos con una apariencia más o menos real.

Por ejemplo:

  • $faker->sentence nos va a generar una frase estilo “Lorem ipsum”.
  • $faker->name va a generar un nombre inventado pero que parece un nombre (eso sí, van a ser nombres del estilo de “Mr. Caesar Smith”).
  • $faker->dateTime va a generar una fecha.

Hay otras posibilidades, como por ejemplo:

  • $faker->safeEmail
  • $faker->userName
  • $faker->url

Nombres en español

Si queremos que los nombres inventados sean en español podemos añadir la siguiente línea:

$faker->addProvider(new Faker\Provider\es_ES\Person($faker));

De modo que el factory quedaría:

$factory->define(App\Noticia::class, function (Faker\Generator $faker) {
    $faker->addProvider(new Faker\Provider\es_ES\Person($faker));
    return [
        'titulo' => $faker->sentence,
        'autor' => $faker->name,
        'fecha_publicacion' => $faker->dateTime,
    ];
});

Añadir nuestro Seeder a la lista de Seeders

El último paso es decirle a Laravel que use el Seeder que hemos creado. Para eso editamos el fichero:

database/seeds/DatabaseSeeder.php

Esta es la clase que se encarga de llamar a todos los seeders que queramos. En nuestro ejemplo vamos a llamar al seeder que acabamos de crear NoticiasSeeder:

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $this->call(NoticiasSeeder::class);
    }
}

Hemos añadido la línea:

$this->call(NoticiasSeeder::class);

que será la encargada de llamar a nuestro Seeder.

Añadir los datos

El último paso es usar Artisan para generar los datos para nuestra tabla. Para eso usa el comando:

$ php artisan db:seed

Si todo va bien veremos el mensaje:

Seeded: NoticiasSeeder

Ver los datos

Los datos deberían estar ya en nuestra tabla noticias. Podemos comprobarlo entrando en nuestra base de datos. En mi caso he usado MySQL:

mysql> select * from noticias;
+----+---------------------+---------------------+-------------------------------------------------------+--------------------+---------------------+
| id | created_at          | updated_at          | titulo                                                | autor              | fecha_publicacion   |
+----+---------------------+---------------------+-------------------------------------------------------+--------------------+---------------------+
|  1 | 2016-09-14 08:53:42 | 2016-09-14 08:53:42 | Earum recusandae corrupti itaque nostrum iste maxime. | Destiney Gorczany  | 1999-04-23 18:09:34 |
|  2 | 2016-09-14 08:53:42 | 2016-09-14 08:53:42 | Non minus odio in autem amet molestias.               | Kristopher Stanton | 2006-02-18 23:37:07 |
|  3 | 2016-09-14 08:53:42 | 2016-09-14 08:53:42 | Tempore fuga aut placeat.                             | Ephraim Gislason   | 1981-09-22 10:12:15 |
|  4 | 2016-09-14 08:53:42 | 2016-09-14 08:53:42 | Occaecati ut voluptate excepturi quasi.               | Mr. Caesar Smith   | 2010-10-11 15:47:52 |
|  5 | 2016-09-14 08:53:42 | 2016-09-14 08:53:42 | Odio ex est explicabo quam.                           | Hassie Abbott      | 1999-02-08 05:26:17 |
+----+---------------------+---------------------+-------------------------------------------------------+--------------------+---------------------+

Limpieza de los datos

Si no queremos que se añadan nuevos datos cada vez que ejecutemos el Seeder podemos hacer limpieza vaciando la tabla antes. Podríamos editar NoticiasSeeder y añadir:

DB::table('noticias')->truncate();

De modo que quedaría:

    public function run()
    {
        DB::table('noticias')->truncate();

        factory(App\Noticia::class, 5)->create();
    }

También podríamos hacer la limpieza en la clase DatabaseSeeder para tenerlo todo junto.

Autor:
Nivel: Intermedio
Palabras clave:
Fecha publicado:
Fecha actualizado: 15-09-2016

Otros capítulos de la misma serie

Este capítulo es parte de la serie: Laravel pearls.

Y muchos más en preparación.

Disponible en los planes: Laravel hero