Skip to content

10. Factories y Seeders en Laravel

Los Seeders y Factories son herramientas fundamentales en Laravel para poblar bases de datos con información de prueba o inicial. Mientras que los seeders permiten insertar datos predefinidos, las factories generan datos aleatorios siguiendo un patrón, lo que resulta especialmente útil para pruebas y desarrollo.

Para crear un nuevo seeder, utiliza el comando make:seeder de Artisan:

Terminal window
php artisan make:seeder UserSeeder

Este comando generará una nueva clase en el directorio database/seeders con la siguiente estructura básica:

<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class UserSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
//
}
}

Hay varias formas de ejecutar los seeders:

Terminal window
php artisan db:seed

Este comando ejecuta los seeders sin modificar la estructura de la base de datos, por lo que es seguro para usar en entornos con datos existentes.

Terminal window
php artisan db:seed --class=UserSeeder

El archivo DatabaseSeeder.php actúa como un punto central para organizar todos tus seeders:

<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*/
public function run(): void
{
// Llama a otros seeders
$this->call([
UserSeeder::class,
ProductSeeder::class,
CategorySeeder::class,
]);
}
}

Insertar Datos Manualmente desde un Seeder

Section titled “Insertar Datos Manualmente desde un Seeder”

Puedes insertar datos directamente en la base de datos desde un seeder de varias formas:

use App\Models\User;
public function run(): void
{
User::create([
'name' => 'Admin User',
'email' => 'admin@example.com',
'password' => bcrypt('password'),
'role' => 'admin',
]);
}

Un Factory es una clase que define cómo se deben generar los datos ficticios para un modelo específico. Laravel utiliza la biblioteca Faker para generar datos aleatorios realistas como nombres, correos electrónicos, direcciones, etc.

Para crear un nuevo factory, utiliza el comando make:factory de Artisan:

Terminal window
php artisan make:factory ProductFactory

Si quieres asociar el factory a un modelo específico:

Terminal window
php artisan make:factory ProductFactory --model=Product

Esto generará una clase en el directorio database/factories con la siguiente estructura:

<?php
namespace Database\Factories;
use App\Models\Product;
use Illuminate\Database\Eloquent\Factories\Factory;
class ProductFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Product::class;
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
//
];
}
}

Faker proporciona muchos métodos para generar diferentes tipos de datos aleatorios:

public function definition(): array
{
return [
'name' => $this->faker->productName(),
'description' => $this->faker->paragraph(),
'price' => $this->faker->randomFloat(2, 10, 1000),
'stock' => $this->faker->numberBetween(0, 100),
'category_id' => $this->faker->numberBetween(1, 5),
'is_active' => $this->faker->boolean(80), // 80% de probabilidad de ser true
'created_at' => $this->faker->dateTimeBetween('-1 year', 'now'),
];
}

Faker ofrece una amplia variedad de métodos para generar datos falsos realistas. Aquí tienes una lista de las funciones más comunes organizadas por categoría:

// Nombres y datos personales
$this->faker->name(); // 'Dr. Zane Stroman'
$this->faker->firstName(); // 'Lucy'
$this->faker->lastName(); // 'Cechtelar'
$this->faker->title($gender = null); // 'Ms.', 'Dr.', etc.
$this->faker->suffix(); // 'Jr.', 'Sr.', etc.
$this->faker->userName(); // 'leone.fahey'
$this->faker->password(); // 'k&|X+a45*2['
// Contacto
$this->faker->email(); // 'tkshlerin@collins.com'
$this->faker->safeEmail(); // 'king.alford@example.org'
$this->faker->phoneNumber(); // '201-886-0269 x3767'
$this->faker->phoneNumberWithExtension(); // '201-886-0269 x3767'
// Documentos de identidad
$this->faker->uuid(); // '7e57d004-2b97-0e7a-b45f-5387367791cd'
$this->faker->ean13(); // '4006381333931'
$this->faker->ean8(); // '73513537'

Puedes utilizar factories dentro de tus seeders para generar datos aleatorios:

use App\Models\User;
public function run(): void
{
// Crear un único registro
User::factory()->create();
// Crear un registro con atributos específicos
User::factory()->create([
'name' => 'Admin User',
'email' => 'admin@example.com',
]);
}

Generar múltiples registros con Factories

Section titled “Generar múltiples registros con Factories”

Puedes generar múltiples registros fácilmente con el método count:

// Crear 50 usuarios
User::factory()->count(50)->create();
// Crear 10 usuarios activos
User::factory()->count(10)->state(['is_active' => true])->create();

Laravel permite establecer relaciones entre modelos dentro de los factories:

// En UserFactory
public function definition(): array
{
return [
'name' => $this->faker->name(),
'email' => $this->faker->unique()->safeEmail(),
// otros campos
];
}
// Crear un usuario con un perfil
public function withProfile(): static
{
return $this->has(Profile::factory(), 'profile');
}
// Uso:
$user = User::factory()->withProfile()->create();

Ejecutar solo seeders o factories en entornos con datos existentes

Section titled “Ejecutar solo seeders o factories en entornos con datos existentes”

Cuando trabajas en un entorno con datos existentes y solo necesitas añadir datos adicionales sin modificar la estructura de la base de datos, puedes usar los siguientes comandos:

Terminal window
# Ejecutar todos los seeders sin rehacer migraciones
php artisan db:seed
# Ejecutar un seeder específico sin rehacer migraciones
php artisan db:seed --class=UserSeeder
# Ejecutar un factory directamente desde tinker
php artisan tinker
>>> App\Models\User::factory()->count(10)->create(); // Crear 10 usuarios
>>> exit

Puedes combinar migraciones y seeders en un solo comando, lo que es especialmente útil durante el desarrollo:

Terminal window
# Refresca la base de datos y ejecuta los seeders
php artisan migrate:fresh --seed
# Ejecuta migraciones pendientes y luego los seeders (no elimina datos existentes)
php artisan migrate --seed
# Refresca solo algunas tablas y ejecuta los seeders
php artisan migrate:fresh --seed --path=database/migrations/2023_*
  1. Organiza tus seeders: Usa el DatabaseSeeder como punto central y organiza los seeders en un orden lógico considerando las dependencias entre tablas.

  2. Usa estados en factories: Define estados para casos especiales:

// En UserFactory
public function admin(): static
{
return $this->state([
'role' => 'admin',
'is_admin' => true,
]);
}
// Uso:
User::factory()->admin()->create();
  1. Datos consistentes: Asegúrate de que los datos generados sean consistentes y cumplan con las restricciones de tu base de datos.

  2. Separación de entornos: Considera tener seeders específicos para diferentes entornos (desarrollo, pruebas, producción).

A continuación se muestra un ejemplo completo de cómo usar factories y seeders juntos:

<?php
namespace Database\Factories;
use App\Models\Category;
use App\Models\Product;
use Illuminate\Database\Eloquent\Factories\Factory;
class ProductFactory extends Factory
{
protected $model = Product::class;
public function definition(): array
{
return [
'name' => $this->faker->words(3, true),
'description' => $this->faker->paragraph(),
'price' => $this->faker->randomFloat(2, 10, 1000),
'stock' => $this->faker->numberBetween(0, 100),
'is_active' => true,
];
}
public function inactive(): static
{
return $this->state(['is_active' => false]);
}
public function featured(): static
{
return $this->state([
'is_featured' => true,
'discount_percentage' => $this->faker->numberBetween(10, 30),
]);
}
}

Los factories y seeders son herramientas poderosas en Laravel que te permiten generar datos de prueba de manera eficiente. Utilízalos para crear un entorno de desarrollo robusto, realizar pruebas efectivas y proporcionar datos iniciales para tu aplicación.

🐝