Laravel | Fabryka czyli factory
Zabawy z bazą danych mają to do siebie, że czasem musimy usunąć wszystkie wpisy, a niekiedy zrobimy to zupełnie przypadkowo. Taka sytuacja pozbawia Nas możliwości “zabawy” z danymi, gdyż musimy jeszcze raz wprowadzić jakieś danie. Co gdyby jednym poleceniem dodać 1000 wpisów na bloga, albo 10 tys użytkowników ze zdjęciami profilowymi, adresami mailowymi, co więcej – te dane będą losowo generowane także nie będą się powtarzać – zaciekawiony? W tym wpisie opowiemy sobie o factory, czyli fabryce wbudowanej w Laravel-a.
Przejdźmy do konsoli i wpiszmy w niej:
php artisan make:factory PostFactory
Takie polecenie pozwoli wygenerować plik:
database/factories/PostFactory.php
a tak będzie wyglądał w środku:
<?php /** @var \Illuminate\Database\Eloquent\Factory $factory */ use App\Model; use Faker\Generator as Faker; $factory->define(Model::class, function (Faker $faker) { return [ // ]; });
Na samym wstępie, musimy zadeklarować do jakiego modelu Ta konkretna fabryka (gdyż możemy ich mieć dowolną ilość) została utworzona dla modelu Post, więc to zapiszmy:
$factory->define(Model::class, function (Faker $faker) na $factory->define(App\Post::class, function (Faker $faker)
Fabryka ta korzysta z biblioteki dostępnej dla php (https://github.com/fzaninotto/Faker), a wracając do kodu, zwraca on tablicę asocjacyjną, w której możemy zadeklarować pola jakie ma produkować, np:
'title' => $faker->sentence(6), //Utwórz zdanie które posiada 6 słów 'content' => $faker->paragraph(7), //Utwórz akapit, który ma 7 zdań 'date' => now(), // możemy używać dostępnych funkcji przez Laravel 'type' => 'text' // możemy także na sztywno wprowadzać dane
Aby wykonać taki faker post, przechodzimy do konsoli i wpisujemy:
php artisan tinker factory(App\Post::class)->make()
Jak można zaobserować post został wygenerowany:

Zapewne domyślasz się, że skoro został wygenerowany, to nie znaczy, że automatycznie jest dodany do bazy danych 😉 Abny go automatycznie dodać powinniśmy na końcu polecenia użyć metody ->save();
factory(App\Post::class)->make()->save();
Aby to lepiej wytłumaczyć warto pokazać cały kod i go przeanalizować:
$factory->define(App\Post::class, function (Faker $faker) { return [ 'title' => $faker->sentence(5), 'content' => $faker->paragraph(5), 'date' => now(), 'type' => 'text' ]; }); $factory->state(App\Post::class, 'image', function (Faker $faker) { return [ 'content' => null, 'date' => now(), 'type' => 'photo', 'image' => $faker->imageUrl(1200, 800) ]; });
Zacznijmy od początku omawiać drugi faker post. Pierwsza różnica zamiast define
użyliśmy state
(linia 10). Chodzi o to że pierwszy post jest zadeklarowany a drugi jest potomkiem pierwszego. Aby to lepiej zrozumieć wytłumaczę to na pierwszym elemencie tablicy asocjacyjnej jakim jest title
(linia 3). Zwróć uwagę, że jest tylko w pierwszej fabryce a w drugiej go nie ma – prawda? a skoro nie zadeklarowaliśmy go w drugiej to, automatycznie zostanie dodany z pierwszego. Inaczej się ma sprawa z content
. W pierwszym jest zadeklarowane, a w drugim jest zadeklarowane jako null
. Oznacza to tyle, że widzimy, że jest zadeklarowany powyżej ale my go świadomie nie chcemy. Możemy dodać oczywiście więcej pól, które nie były zadeklarowane powyżej jak, np: image
. W nim odwołujemy się do biblioteki $faker i mówimy jej, że chcemy tu ścieżkę do obrazka (z zewnętrznego źródła), a sam obrazem ma mieć rozmiary 1200px na 800px. Jednak to nie jedyna zmiana. Jak zapewne rzuciło Ci się w oczy przy deklarowaniu instancji doszedł jeden parametr – 'image'
(linia 10). Jest tu on po to, żebyśmy przy tworzeniu “fejkowego” posta powiedzieli fabryce który typ postu konkretnie ma utworzyć (typu 'text'
, czy typu image
).
Ok, ale jak teraz wywołać drugą fabrykę? Wystarczy, że przejdziemy do <code>php artisan tinker</code> i posłużymy się takim poleceniem.
php artisan tinker factory(App\Post::class)->state('image')->make()
Oczywiście pamiętajmy, że powyższy kod tylko generuje “fejkowy” post, więc jeśli chcielibyśmy aby odrazu został zapisany musimy na końcu dodać metodę <code>->save()</code>
factory(App\Post::class)->state('image')->make()->save()
No dobrze, wiemy już jak generować posty ale, co mam tera 1000 razy powielać polecenia, żeby dodać 1000 wpisów? 🙂 – Nie ale przejdziemy do tego w artykule z seed-owanie w Laravel.