[5 z 5] Laravel PHP: Model

Wiesz już jak stworzyć nową klasę rozszerzającą klasę bazową Model w Laravelu. Dodałeś również obsługę bazy danych SQLite oraz, bazując na modelu, stworzyłeś nową tabelę o odpowiedniej strukturze.

Teraz spróbujemy wspólnie wypełnić tę tabelę testowymi danymi i nauczymy się wyświetlać te dane na ekranie.

Dane testowe oraz Factory w Laravelu

Laravel wychodzi nam na przeciw i oferuje gotowe rozwiązanie do generowania danych testowych – model factory oraz klasę Faker.

Factory (z ang. Fabryka) to mechanizm do tworzenia nowych wierszy dla danego modelu. Definiujemy w nim jakimi danymi mają się wypełniać.

Do generowania danych testowych – tzw. dummy data, służy klasa Faker. W domyślnym projekcie Laravela (czyli również w naszym) istnieje już jedna fabryka dla Usera, która korzysta z klasy Faker. Zobacz sobie zawartość pliku /database/factories/UserFactory.php:

<?php

use Faker\Generator as Faker;

/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| This directory should contain each of the model factory definitions for
| your application. Factories provide a convenient way to generate new
| model instances for testing / seeding your application's database.
|
*/

$factory->define(App\User::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
        'remember_token' => str_random(10),
    ];
});

Jak widzisz, mamy tu zdefiniowaną wartość dla każdej z kolumn. Korzystanie z Fakera jest opcjonalne – to klasa do generowania danych testowych, stąd name i email korzystają z niej do wygenerowania odpowiednich danych. Natomiast password i token są ustawiane bez użycia Fakera.

Teraz stwórzmy analogicznie własną fabrykę dla naszego modelu Article.

Własne factory dla modelu

Podobnie jak przy innych poleceniach dla Laravela, skorzystamy tutaj z konsoli i polecenia php artisan.

Ustaw się w folderze projektu i wykonaj:

php artisan make:factory ArticleFactory

W rezultacie dostaniesz odpowiedź, że Factory created successfully.

Teraz możesz przejść do folderu database/factories i otworzyć nowoutworzony plik ArticleFactory.php:

<?php

use Faker\Generator as Faker;

$factory->define(Model::class, function (Faker $faker) {
    return [
        //
    ];
});

Jest to pusty template dla nowej fabryki. Masz już tutaj wszystko przygotowane, by zadeklarować wartości dla pól. Jedyne co musisz zmienić, to nazwę klasy bazowej Model (Model::class) musisz zamienić na nazwę naszego modelu Article (App\Article::class).

Kolejną ważną kwestią jest zwrócenie wypełnionych pól obiektu.

Model Article zawiera (bazując na stworzonej migracji w poprzednim artykule):

<?php
Schema::create('articles', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title', 255);
            $table->text('content');
            $table->timestamps();
        });

Pola: id, title, content i daty (utworzenia i modyfikacji).

Pole id oraz daty są ustawiane automatycznie i nie będziemy nimi sterować. Interesują nas parametry title oraz content. Pierwszy jest stringiem o maksymalnej długości 255 znaków, drugi dłuższym tekstem. Zobacz teraz, jak możemy wykorzystać klasę Faker, by stworzyć nowy artykuł w bazie (pracując dalej na ArticleFactory.php):

<?php

use Faker\Generator as Faker;

$factory->define(App\Article::class, function (Faker $faker) {
    return [
        'title' => $faker->sentence,
        'content' => $faker->paragraph
    ];
});

Tym sposobem poprosiliśmy Fakera o wygenerowanie zdania jako testowego tytułu oraz paragrafu jako testowego contentu. Zobacz teraz, jak wykorzystać stworzoną fabrykę w faktycznym dodawaniu danych do bazy.

Seed w Laravelu

Mamy już definicję danych, reguły tworzenia nowych danych testowych oraz połączenie do bazy. Czas teraz na ostatni element, czyli database seeder. Dzięki niemu wrzucimy nowe dane do bazy, korzystając z fabryki artykułów.

Korzystając z konsoli wpisz:

php artisan make:seeder ArticleTableSeeder

W rezultacie otrzymasz wiadomość, że Seeder created successfully. Od razu otwórz nowy plik w katalogu database/seeds i zobacz, jak możemy skorzystać z utworzonej fabryki dla modelu:

<?php

use Illuminate\Database\Seeder;

class ArticleTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(App\Article::class, 5)->create();
    }
}

Pozwoliłem sobie dopisać obsługę metody run, która po utworzeniu nowego seedera jest pusta.

Wewnątrz niej korzystam z metody factory, która zwraca fabrykę dla podanego modelu (w naszym przypadku to klasa Article). Jako drugi argument możemy podać ilość wierszy do wygenerowania (w moim przypadku 5). Po czym metoda create wygeneruje i wstawi wiersze do bazy.

Teraz ostatnim krokiem będzie dodanie obsługi nowego seedera w klasie DatabaseSeeder i uruchomienie polecenia db:seed. Możesz to zrobić poprzez edycję pliku DatabaseSeeder.php wewnątrz folderu database/seeds. Wyrzuć zakomentowanego seedera tabeli Users i umieść tam naszego nowego seedera:

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call(ArticleTableSeeder::class);
    }
}

Teraz, w konsoli, możesz uruchomić polecenie:

php artisan db:seed

Czego rezultatem jest umieszczenie nowych danych w bazie.

Jeśli zobaczysz sobie, co dzieje się pod spodem, zauważysz konkretny kod SQL wykorzystany do wrzucenia danych:

insert into "articles" ("title", "content", "updated_at", "created_at") values (An
imi maxime et corporis quia tempore corporis incidunt., Deserunt esse adipisci necessitatib
us aut. Voluptas qui voluptas nihil porro temporibus eligendi est laudantium. Quia quia ut
provident voluptas consequuntur error tenetur itaque. Aliquam et error quidem ut., 2019-04-
07 09:39:23, 2019-04-07 09:39:23)

Pobieranie danych z bazy

Teraz jesteś w pełni przygotowany, by pobrać dane z bazy z wykorzystaniem klasy Article. Zaraz pokażę jak to zrobić.

Zanim stworzymy stronę dedykowaną artykułom, wykorzystajmy nasz kontroler z poprzednich lekcji i wrzućmy tytuł pierwszego znalezionego artykułu zamiast Hello World w metodzie hello.

Otwórz plik ArticleController.php i zobacz jak łatwo jest pobrać dane z bazy i przekazać je do widoku:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ArticleController extends Controller
{
    public function index()
    {
        $articles = \App\Article::all();
        return view("hello")->with("hello", $articles[0]->title);
    }
}

Nawet nie musimy tworzyć nowego obiektu. Mamy do dyspozycji statyczne metody zwracające nam wyniki dla zadanych kryteriów.

Po zapisaniu pliku, wejściu na stronę i odwiedzeniu adresu http://127.0.0.1/hello, zobaczymy tytuł pierwszego artykułu w naszej bazie:

Dane z modelu na stronie

Potrafisz stworzyć widok w Laravelu, potrafisz użyć kontrolera do zwrócenia widoku oraz nauczyłeś się pisać własne modele wraz z obsługą bazy danych i generowaniem danych testowych.

Czas połączyć zdobytą wiedzę i stworzyć w pełni działający fragment aplikacji MVC.

Skorzystamy z naszego modelu Article i wykorzystamy dane testowe w bazie, by wyświetlić listę artykułów na stronie.

Do tego celu przyda nam się nowa metoda w kontrolerze ArticleController. Otwórz ten plik i dodaj metodę showAll poniżej metody index:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ArticleController extends Controller
{
    public function index()
    {
        $articles = \App\Article::all();
        return view("hello")->with("hello", $articles[0]->title);
    }

    public function showAll()
    {
        $articles = \App\Article::all();
        return view("blog")->with("articles", $articles);
    }
}

W metodzie showAll() najpierw pobieramy wszystkie artykuły, po czym zwracamy widok o nazwie „blog” wyposażony w zmienną $articles. Takiego widoku jeszcze nie mamy, zatem musimy go stworzyć.

Nowy widok dla artykułów

Kliknij prawym przyciskiem myszy w folder resources/views i dodaj nowy plik o nazwie blog.blade.php:

Nowy widok blog.blade.php

Tym sposobem dodałeś nowy widok, który wyświetli nam listę artykułów.

Stworzymy prosty layout, który wyświetli artykuły jeden pod drugim. Wykorzystamy większość tego, co już pisaliśmy w hello.blade.php i dodamy iterowanie po liście artykułów metodą foreach.

Zobacz jak to zrobić w kodzie. Otwórz plik i napisz:

<!doctype html>
<html lang="{{ app()->getLocale() }}">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Blog</title>
    </head>
    <body>
        <h1>Witaj na blogu</h1>
        @isset($articles)
            <h2>Wpisów na blogu: {{ count($articles) }}</h2>
            @foreach($articles as $a)
                <h3>{{ $a->title }}</h3>
                <p>{{ $a->content }}</p>
                <hr />
            @endforeach
        @endisset
        <p>
            <a href="{{ url('/') }}">Wróć na główną</a>
        </p>
    </body>
</html>

Poza tym, że prezentujemy wszystkie artykuły, to dodatkowo pokazujemy ich liczbę na samej górze strony.

Przeglądając kod linijka po linijce, zaraz za witającym nagłówkiem h1, sprawdzamy czy istnieje zmienna $articles. Jeśli tak, wchodzimy do bloku kodu i wyświetlamy sumę wpisów w nagłówku h2. Wykorzystujemy do tego funkcję count na tablicy $articles.

Poniżej, korzystając z pętli foreach, przechodzimy po każdym artykule i zapisujemy go do zmiennej $a. Teraz, w zmiennej $a kryje się pojedynczy artykuł. Dzięki temu możemy wyświetlić jego tytuł (w ramach h3) oraz content wewnątrz znacznika p.

Następnie kończymy wykonywanie pętli foreach oraz zamykamy blok isset. Na samym końcu wyświetlamy przycisk powrotu do strony głównej.

Ustawiamy routing

Ostatnią brakującą rzeczą, potrzebną do wyświetlenia tej strony, jest routing.

Wejdź do pliku routes/web.php i dodaj nową ścieżkę powiązaną z utworzoną metodą z kontrolera:

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::get('/hello', 'ArticleController@index');

Route::get('/blog', 'ArticleController@showAll');

Teraz nauczyłeś swoją aplikację, że wpisując baseAddress/blog uruchomi się metoda showAll z kontrolera ArticleController.

Pozostaje sprawdzić, czy to faktycznie zadziała. Do uruchomienia serwera php służy komenda:

php artisan serve

Po jej uruchomieniu w konsoli, możesz odwiedzić stronę http://127.0.0.1/blog. W moim przypadku efekt był następujący:

Efekt końcowy prac w laravelu

Jak widzisz, strona wypełniła się wpisami z bazy danych. Ponieważ uruchomiłem polecenie db:seed kilka razy, mam tych artykułów aż 20. Jeśli seedowałeś tylko raz, powinieneś zobaczyć 5 artykułów.

Podsumowanie

Tym sposobem dobrnęliśmy do końca tego mini-tutoriala z Laravela. Mam nadzieję, że się podobało.

Podsumujmy co udało nam się dzisiaj uzyskać.

Po pierwsze, stworzyłeś własną fabrykę dla modelu Article i wykorzystałeś klasę Faker do tworzenia danych testowych.

Po drugie, napisałeś własnego seedera, który wypełni tabelę wygenerowanymi danymi testowymi.

Po trzecie, uruchomiłeś seedera w głównej klasie DatabaseSeeder i nauczyłeś się korzystać z polecenia db:seed.

Po czwarte, pobrałeś dane bazy danych i wyświetliłeś je w widoku.

Po piąte, stworzyłeś nowy widok i metodę w kontrolerze, by wyświetlić kompletną listę wpisów z bazy danych.

Całkiem nieźle! Sporo już potrafisz.

Jeśli się podobało lub masz jakieś pytania, zostaw komentarz poniżej. Będzie mi miło jeśli polecisz ten materiał znajomym.

Przejdź do artykułu poświęconego frameworkowi i spisu wszystkich materiałów tutaj >>> Laravel.

Jeśli nie do końca rozumiesz działanie wzorca MVC (Model, View, Controller) zachęcam do zapoznania się z kursem MVC w PHP od zera.

Dzięki i do następnego razu!

3 Responses on this post

  1. Bardzo ciekawy artykuł na temat Laravela. Często pojawia się ten framework w wymaganiach na stanowisko Juniora PHP. Dlatego postanowiłem się z nim zaznajomić. Tekst ten w prosty i szybki sposób wyjaśnia jego podstawowe możliwości . Wcześniej przerobiłem kurs tworzenia wzorca MVC od zera w PHP i jest on świetnym uzupełnieniem, żeby bez problemu się orientować i rozumieć co się dzieje pod maską. Pozdrawiam serdecznie.

  2. Czy po poleceniu: php artisan make:seeder ArticleTableSeeder
    wygenerowana zostanie klasa ArticleSeeder jak jest w artykule czy ArticleTableSeeder jak w poleceniu?

    1. Tak Sławku, masz rację. Zostanie wygenerowana klasa ArticleTableSeeder.

      Zaraz poprawię w artykule.

      Dzięki i pozdrawiam!

Comments are closed.