Poznajemy seeding z dwoma typami relacji (jeden do jednego i jeden do wielu). Dzięki temu możemy szybko wytworzyć fejkowe dane do manualnych testów aplikacji.
Ok, przypomnijmy na czym stanęliśmy. AdresFactory:
class AddressFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'city' => fake()->city(),
'street' => fake()->streetName()
];
}
}
PersonFactory z różnymi stanami (male, female, adults, kids):
class PersonFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'firstName' => fake()->firstName(),
'lastName' => fake()->lastName(),
'age' => fake()->numberBetween(16, 60),
'created_at' => fake()->dateTimeBetween('-2 years'),
'updated_at' => fake()->dateTimeBetween('created_at', 'now')
];
}
public function adults()
{
return $this->state(function (array $attributes) {
return [
'age' => fake()->numberBetween(19, 60),
];
});
}
public function kids()
{
return $this->state(function (array $attributes) {
return [
'age' => fake()->numberBetween(14, 18),
];
});
}
public function male()
{
return $this->state(function (array $attributes) {
return [
'firstName' => fake()->firstName('male'),
'lastName' => fake()->lastName('male'),
];
});
}
public function female()
{
return $this->state(function (array $attributes) {
return [
'firstName' => fake()->firstName('female'),
'lastName' => fake()->lastName('female'),
];
});
}
}
PersonSeeder z relacją 1 do 1 Person hasOne Address, Address belongsTo person:
use App\Models\Person;
use App\Models\Address;
class PersonSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
Person::factory()
->count(5)
->male()
->create()
->each(function($person){
$person->address()->save(Address::factory()->make());
});
Person::factory()
->count(5)
->female()
->create()
->each(function($person){
$person->address()->save(Address::factory()->make());
});
Person::factory()
->count(5)
->kids()
->create()
->each(function($person){
$person->address()->save(Address::factory()->make());
});
Person::factory()
->count(5)
->adults()
->create()
->each(function($person){
$person->address()->save(Address::factory()->make());
});
}
}
A co dodać chcemy? Notes:
- relacja jeden do wielu
- Person hasMany Note
- Note belongsTo Person
Ok, NoteFactory:
*/
class NoteFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'title' => fake()->sentence(6),
'content' => fake()->sentence(12)
];
}
}
Argument przekazany do sentence to jest liczba wyrazów. Ok, teraz PersonSeeder:
use App\Models\Person;
use App\Models\Address;
use App\Models\Note;
class PersonSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
Person::factory()
->count(5)
->male()
->create()
->each(function($person){
$person->address()->save(Address::factory()->make());
$notes = Note::factory()
->count(random_int(1,5))
->make();
$person->notes()->saveMany($notes);
});
Person::factory()
->count(5)
->female()
->create()
->each(function($person){
$person->address()->save(Address::factory()->make());
$notes = Note::factory()
->count(random_int(1,5))
->make();
$person->notes()->saveMany($notes);
});
Person::factory()
->count(5)
->kids()
->create()
->each(function($person){
$person->address()->save(Address::factory()->make());
$notes = Note::factory()
->count(random_int(1,5))
->make();
$person->notes()->saveMany($notes);
});
Person::factory()
->count(5)
->adults()
->create()
->each(function($person){
$person->address()->save(Address::factory()->make());
$notes = Note::factory()
->count(random_int(1,5))
->make();
$person->notes()->saveMany($notes);
});
}
}
Czemu tak? Cóż:
- factory wywołuje fabrykę
- count podaje ile razy z fabryki skorzystać
- dalej mamy stan (kids, adults, male, female)
- create oznacza utwórz
- each pozwala po utworzeniu coś jeszcze wykonać (np. zająć się relacjami)
- do person odwołujemy się do address->save, aby zapisać 1 do 1
- aby utworzyć adres bierzemy fabrykę i make (make tworzy bez zapisywania, zostanie zapisane przez save)
- tak samo możemy utworzyć przez make kilka notatek
- jako że relacja jeden do wielu i samych notatek jest potencjalnie więcej niż jedna używamy saveMany
No i najważniejsze, zawsze zapominam tej komendy:
php artisan db:seed --class=PersonSeeder
W bazie danych już mamy dobrze potworzone rekordy z relacjami.