9: Generando e insertando datos de prueba para tu portafolio con Laravel
9: Generando e insertando datos de prueba para tu portafolio con Laravel
Introducción
En este tutorial vamos a crear y ejecutar Factories y Seeders para poblar nuestra base de datos con información de prueba. Lo interesante de esta clase es que implementaremos un enfoque particular para manejar los colores e iconos que funcionan con Tailwind CSS, asegurando que los estilos se apliquen correctamente en el frontend.
¿Qué son los Factories y Seeders?
Factories: Clases que generan datos ficticios para tus modelos usando la librería Faker
Seeders: Clases que ejecutan los factories para insertar datos en la base de datos
Paso 1: Crear los Factories
Primero, crearemos los factories para nuestros modelos:
php artisan make:factory ProjectFactory --model=Project
php artisan make:factory SkillFactory --model=SkillPaso 2: Configurar el Factory de Skills
Abre database/factories/SkillFactory.php y define la estructura:
<?php
namespace Database\Factories;
use App\Models\Skill;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Facades\File;
class SkillFactory extends Factory
{
protected $model = Skill::class;
// Método estático para obtener colores de fondo disponibles
public static function getAvailableBackgroundColors()
{
$path = resource_path('json/customization.json');
$content = File::get($path);
$data = json_decode($content, true);
return $data['background'] ?? [];
}
public function definition(): array
{
$backgroundColors = self::getAvailableBackgroundColors();
return [
'name' => $this->faker->unique()->word(),
'color' => $this->faker->randomElement($backgroundColors),
'category' => $this->faker->randomElement(['Frontend', 'Backend', 'DevOps', 'Database', 'Mobile']),
'level' => $this->faker->numberBetween(30, 100),
'is_featured' => $this->faker->boolean(30), // 30% de probabilidad
'order' => $this->faker->numberBetween(0, 10),
];
}
}Paso 3: Crear el archivo de configuración JSON
Ahora crearemos el archivo que contendrá los colores e iconos disponibles. Este archivo es crucial porque Tailwind CSS necesita conocer las clases que se van a utilizar en el frontend.
Crea la carpeta y el archivo:
mkdir -p resources/json
touch resources/json/customization.jsonAbre resources/json/customization.json y agrega:
{
"background": [
"indigo",
"green",
"yellow",
"blue",
"pink",
"red",
"purple",
"orange",
"teal",
"cyan",
"rose",
"amber",
"lime",
"emerald",
"violet",
"fuchsia"
],
"text": [
"indigo",
"green",
"yellow",
"blue",
"pink",
"red",
"purple",
"orange",
"teal",
"cyan",
"rose",
"amber",
"lime",
"emerald",
"violet",
"fuchsia"
],
"icons": [
"code",
"database",
"server",
"cloud",
"mobile",
"desktop",
"puzzle",
"rocket",
"star",
"heart",
"camera",
"music",
"book",
"coffee",
"laptop",
"globe",
"shield",
"lock",
"key",
"github",
"linkedin",
"twitter"
]
}Paso 4: Configurar el Factory de Projects
Abre database/factories/ProjectFactory.php:
<?php
namespace Database\Factories;
use App\Models\Project;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Facades\File;
class ProjectFactory extends Factory
{
protected $model = Project::class;
// Método estático para obtener colores de texto disponibles
public static function getAvailableTextColors()
{
$path = resource_path('json/customization.json');
$content = File::get($path);
$data = json_decode($content, true);
return $data['text'] ?? [];
}
// Método estático para obtener iconos disponibles
public static function getAvailableIcons()
{
$path = resource_path('json/customization.json');
$content = File::get($path);
$data = json_decode($content, true);
return $data['icons'] ?? [];
}
public function definition(): array
{
$textColors = self::getAvailableTextColors();
$icons = self::getAvailableIcons();
return [
'title' => $this->faker->words(3, true),
'description' => $this->faker->sentence(),
'content' => $this->faker->paragraphs(3, true),
'image_url' => $this->faker->imageUrl(800, 600, 'tech', true, 'Project'),
'github_url' => 'https://github.com/' . $this->faker->userName() . '/' . $this->faker->word(),
'demo_url' => 'https://' . $this->faker->domainName(),
'technologies' => $this->faker->randomElements(['Laravel', 'Vue.js', 'React', 'Tailwind', 'MySQL', 'Docker', 'AWS', 'Python'], 3),
'start_date' => $this->faker->dateTimeBetween('-2 years', 'now'),
'end_date' => $this->faker->optional()->dateTimeBetween('-1 year', 'now'),
'is_featured' => $this->faker->boolean(20),
'is_published' => $this->faker->boolean(90),
'order' => $this->faker->numberBetween(0, 10),
];
}
}Paso 5: Crear los Seeders
Seeder de Skills
php artisan make:seeder SkillSeederAbre database/seeders/SkillSeeder.php:
<?php
namespace Database\Seeders;
use App\Models\Skill;
use Illuminate\Database\Seeder;
class SkillSeeder extends Seeder
{
public function run(): void
{
// Crear 6 habilidades usando el factory
Skill::factory()
->count(6)
->create();
}
}Seeder de Projects
php artisan make:seeder ProjectSeederAbre database/seeders/ProjectSeeder.php:
<?php
namespace Database\Seeders;
use App\Models\Project;
use Illuminate\Database\Seeder;
class ProjectSeeder extends Seeder
{
public function run(): void
{
// Crear 5 proyectos usando el factory
Project::factory()
->count(5)
->create();
}
}Seeder de Experiences
php artisan make:seeder ExperienceSeederAbre database/seeders/ExperienceSeeder.php:
<?php
namespace Database\Seeders;
use App\Models\Experience;
use Illuminate\Database\Seeder;
class ExperienceSeeder extends Seeder
{
public function run(): void
{
Experience::factory()
->count(4)
->create();
}
}Paso 6: Actualizar DatabaseSeeder
Abre database/seeders/DatabaseSeeder.php y agrega los seeders:
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run(): void
{
$this->call([
SkillSeeder::class,
ProjectSeeder::class,
ExperienceSeeder::class,
]);
}
}Paso 7: Crear el Factory de Experiences (Opcional)
Si deseas también tener datos de prueba para experiencias:
php artisan make:factory ExperienceFactory --model=ExperienceAbre database/factories/ExperienceFactory.php:
<?php
namespace Database\Factories;
use App\Models\Experience;
use Illuminate\Database\Eloquent\Factories\Factory;
class ExperienceFactory extends Factory
{
protected $model = Experience::class;
public function definition(): array
{
$startDate = $this->faker->dateTimeBetween('-5 years', '-1 year');
$isCurrent = $this->faker->boolean(30);
return [
'company' => $this->faker->company(),
'position' => $this->faker->jobTitle(),
'logo_url' => $this->faker->imageUrl(100, 100, 'logo', true, 'Company'),
'description' => $this->faker->paragraph(),
'start_date' => $startDate,
'end_date' => $isCurrent ? null : $this->faker->dateTimeBetween($startDate, 'now'),
'is_current' => $isCurrent,
'location' => $this->faker->city() . ', ' . $this->faker->country(),
'achievements' => $this->faker->sentences(3),
'order' => $this->faker->numberBetween(0, 10),
];
}
}Paso 8: Ejecutar los Seeders
Ahora ejecutaremos los seeders para poblar la base de datos:
Opción 1: Ejecutar todos los seeders
php artisan db:seedOpción 2: Ejecutar un seeder específico
php artisan db:seed --class=SkillSeeder
php artisan db:seed --class=ProjectSeederOpción 3: Refrescar la base de datos y ejecutar seeders
php artisan migrate:fresh --seedNota: El comando
migrate:freshelimina todas las tablas y las vuelve a crear, ejecutando luego los seeders.
Paso 9: Verificar los datos insertados
Usando Tinker
php artisan tinker// Ver todas las habilidades
App\Models\Skill::all();
// Ver todos los proyectos
App\Models\Project::all();
// Ver todas las experiencias
App\Models\Experience::all();
// Ver proyectos destacados
App\Models\Project::where('is_featured', true)->get();Usando el navegador
Si tienes configuradas las rutas, puedes visitar:
/projects- Ver todos los proyectos/skills- Ver todas las habilidades/experience- Ver toda la experiencia
El misterio del archivo JSON
¿Por qué estamos usando un archivo JSON para los colores e iconos?
La razón: Tailwind CSS utiliza un compilador JIT (Just-In-Time) que solo incluye las clases que encuentra en tu código fuente. Si los colores e iconos se guardan directamente en la base de datos y se insertan dinámicamente, Tailwind no los detectará y no generará los estilos correspondientes.
La solución: Al mantener estos valores en un archivo JSON que se encuentra en el código fuente, Tailwind puede escanearlo y generar todas las clases necesarias. Además, esto nos permite:
Mantener consistencia: Los mismos colores se usan en todo el sitio
Configuración centralizada: Cambios en un lugar afectan todo el sistema
Optimización: Tailwind solo genera las clases que realmente se usan
Flexibilidad: Fácil de modificar o extender
Posibles errores y soluciones
Error: "Method is not static"
Solución: Asegúrate de que los métodos en los factories sean estáticos:
public static function getAvailableBackgroundColors()Error: "Class not found"
Solución: Verifica los namespaces e imports:
use Illuminate\Support\Facades\File;
use App\Models\Skill;Error: "Cannot redeclare unique()"
Solución: El método unique() de Faker asegura que no haya valores duplicados. Si obtienes este error, aumenta el límite de intentos:
$this->faker->unique($maxRetries = 100)->word()Resumen
✅ Creamos Factories para generar datos de prueba
✅ Configuramos la lectura de colores e iconos desde un archivo JSON
✅ Creamos Seeders para poblar la base de datos
✅ Ejecutamos los seeders correctamente
✅ Verificamos que los datos estén insertados
¡Excelente trabajo! Ahora tenemos datos de prueba en nuestra base de datos que nos permitirán construir y probar las interfaces de usuario. La base de datos está poblada con proyectos, habilidades y experiencia que muestran el potencial de nuestro portafolio.
En la próxima sección comenzaremos a trabajar con las vistas y componentes Vue.js para mostrar esta información de manera atractiva.
Recursos adicionales
¿Tienes dudas sobre el enfoque del archivo JSON? No te preocupes, en las próximas clases veremos por qué es tan importante y cómo se integra con Tailwind CSS para que los estilos funcionen correctamente
Comentarios
Publicar un comentario