Seeders i Factories
Com poblar la base de dades amb dades de prova: seeders, model factories i Faker.
Seeders#
Els seeders permeten inserir dades a la base de dades de manera automatitzada. Són útils per crear dades inicials que l'aplicació necessita per funcionar (com rols, categories o un usuari administrador) i per generar dades de prova durant el desenvolupament.
Per crear un seeder, utilitza la comanda Artisan:
php artisan make:seeder UserSeederAixò genera un fitxer a database/seeders/UserSeeder.php amb un mètode run() on defineixes les dades a inserir:
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Seeder;
class UserSeeder extends Seeder
{
public function run(): void
{
// Crear un usuari administrador específic
User::create([
'name' => 'Admin',
'email' => 'admin@laravelandorra.com',
'password' => bcrypt('password'),
'is_admin' => true,
]);
// Crear 50 usuaris amb dades fictícies
User::factory()->count(50)->create();
}
}El DatabaseSeeder#
El fitxer database/seeders/DatabaseSeeder.php és el seeder principal que s'executa per defecte. Des d'aquí pots cridar altres seeders per organitzar la generació de dades:
class DatabaseSeeder extends Seeder
{
public function run(): void
{
$this->call([
UserSeeder::class,
CategorySeeder::class,
ArticleSeeder::class,
CommentSeeder::class,
]);
}
}Els seeders s'executen en l'ordre en què els llistes. Això és important quan les dades tenen dependències: els usuaris s'han de crear abans que els articles, perquè els articles referencien un user_id.
Executar seeders#
# Executar el DatabaseSeeder (que crida els altres)
php artisan db:seed
# Executar un seeder específic
php artisan db:seed --class=UserSeeder
# Esborrar la BD, executar migracions i seeders
php artisan migrate:fresh --seedModel Factories#
Les factories generen dades fictícies realistes per als teus models. Utilitzen la llibreria Faker, que pot generar noms, correus, adreces, textos, dates i molts altres tipus de dades en múltiples idiomes.
Per crear una factory:
php artisan make:factory ArticleFactoryAixò genera un fitxer a database/factories/ArticleFactory.php. El mètode definition() retorna un array amb els atributs del model i els seus valors generats:
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class ArticleFactory extends Factory
{
public function definition(): array
{
return [
'title' => fake()->sentence(),
'slug' => fake()->unique()->slug(),
'body' => fake()->paragraphs(5, true),
'user_id' => User::factory(),
'published' => fake()->boolean(70),
'published_at' => fake()->dateTimeBetween('-1 year'),
];
}
}El helper fake() proporciona accés a tots els generadors de Faker. Fixa't que user_id utilitza User::factory() en lloc d'un valor estàtic. Això significa que, quan crees un article, Laravel crearà automàticament un usuari associat si no n'especifiques un.
Generadors de Faker habituals#
Faker ofereix una gran varietat de generadors:
fake()->name(); // 'Joan Garcia'
fake()->firstName(); // 'Maria'
fake()->lastName(); // 'Martínez'
fake()->email(); // 'joan.garcia@exemple.com'
fake()->unique()->safeEmail(); // Email únic
fake()->phoneNumber(); // '+34 612 345 678'
fake()->address(); // Adreça completa
fake()->city(); // 'Barcelona'
fake()->country(); // 'Andorra'
fake()->sentence(); // Frase curta
fake()->paragraph(); // Paràgraf
fake()->paragraphs(3, true); // 3 paràgrafs com a string
fake()->text(200); // Text de 200 caràcters
fake()->url(); // 'https://www.exemple.com'
fake()->boolean(70); // true (70% probabilitat)
fake()->numberBetween(1, 100); // Número aleatori
fake()->randomFloat(2, 0, 1000); // 342.57
fake()->dateTimeBetween('-1 year'); // Data de l'últim any
fake()->imageUrl(640, 480); // URL d'imatgeEstats (States)#
Els estats permeten definir variacions d'una factory. Això és molt útil per crear models en estats concrets sense repetir codi:
class ArticleFactory extends Factory
{
public function definition(): array
{
return [
'title' => fake()->sentence(),
'slug' => fake()->unique()->slug(),
'body' => fake()->paragraphs(5, true),
'user_id' => User::factory(),
'published' => false,
'published_at' => null,
];
}
public function published(): static
{
return $this->state(fn (array $attributes) => [
'published' => true,
'published_at' => fake()->dateTimeBetween('-6 months'),
]);
}
public function draft(): static
{
return $this->state(fn (array $attributes) => [
'published' => false,
'published_at' => null,
]);
}
public function byAuthor(User $user): static
{
return $this->state(fn (array $attributes) => [
'user_id' => $user->id,
]);
}
}Ara pots combinar estats per crear models amb característiques específiques:
// 10 articles publicats
Article::factory()->count(10)->published()->create();
// 5 esborranys d'un autor concret
Article::factory()->count(5)->draft()->byAuthor($admin)->create();Utilitzar factories#
Les factories es poden fer servir de moltes maneres:
// Crear un model i desar-lo a la BD
$user = User::factory()->create();
// Crear múltiples models
$users = User::factory()->count(10)->create();
// Crear sense desar (útil per a tests)
$user = User::factory()->make();
// Sobreescriure atributs concrets
$user = User::factory()->create([
'name' => 'Joan',
'email' => 'joan@exemple.com',
]);Factories amb relacions#
Les factories poden crear models amb les seves relacions automàticament:
// Crear un usuari amb 5 articles
$user = User::factory()
->has(Article::factory()->count(5))
->create();
// Sintaxi curta (Laravel infereix el nom de la relació)
$user = User::factory()
->hasArticles(5)
->create();
// Crear un article amb un usuari específic
$article = Article::factory()
->for(User::factory()->state(['name' => 'Admin']))
->create();
// Sintaxi curta
$article = Article::factory()
->forUser(['name' => 'Admin'])
->create();Exemple complet d'un seeder#
Un seeder ben organitzat combina dades fixes amb dades generades per factories:
class DatabaseSeeder extends Seeder
{
public function run(): void
{
// Usuari admin (sempre el mateix)
$admin = User::factory()->create([
'name' => 'Admin',
'email' => 'admin@laravelandorra.com',
'is_admin' => true,
]);
// 20 usuaris normals
$users = User::factory()->count(20)->create();
// 30 articles publicats de l'admin
Article::factory()
->count(30)
->published()
->byAuthor($admin)
->create();
// 50 articles aleatoris d'usuaris normals
Article::factory()
->count(50)
->create();
// 10 esborranys
Article::factory()
->count(10)
->draft()
->create();
}
}Ara, amb php artisan migrate:fresh --seed, tens una base de dades completa amb dades realistes per desenvolupar i testejar l'aplicació.