IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 6 - Jednoduchý redakční systém v Laravel - Migrace

V minulé lekci, Jednoduchý redakční systém v Laravel - Struktura projektu, jsme si popsali strukturu Laravel aplikace a vytvořili si nový projekt.

V dnešním PHP tutoriálu si vysvětlíme, co jsou to migrace a vytvoříme si také svoji vlastní.

Databáze

Údaje k připojení k databázi jsme si nastavili v minulé lekci. O samotné připojení se však starat nemusíme - to za nás řeší framework na pozadí. Pro práci s databází budeme používat Eloquent ORM, kdy každá databázová tabulka má vlastní model (třídu) a skrz tento model pracujeme s danou tabulkou. Jak se ale spravuje databázová struktura v Laravel frameworku?

Generování databázové struktury

Představme si situaci, kdy pracujeme s někým na našem projektu a následně potřebujeme změnit sloupeček v databázové tabulce. Jak tohoto elegantně dosáhnout? Jedním z řešení je sdílet MySQL kód této změny s dalšími vývojáři dané aplikace. To je však velice neefektivní a nespolehlivé. Při nahrávání změn na produkční server se může na některé části MySQL kódu zapomenout a to by způsobilo nefunkčnost aplikace. Jenže takováto situace nesmí nastat u reálné aplikace, zákazník by asi nebyl moc spokojený :) Z tohoto a dalších důvodů vznikly migrace.

Migrace jsou něco jako verze databáze. Modifikujeme skrz ně databázovou strukturu pomocí PHP kódu přes builder nebo spouštěním MySQL příkazů. Výhodou migrací je, že se vykonají pouze jednou. Navíc se v nich můžeme vracet zpět, což se hodí, pokud uděláme nějakou chybu při vývoji.

Migrace najdeme ve složce database/migrations/ a pokud si tuto složku nyní otevřeme, zjistíme, že již obsahuje 3 soubory. Jeden nám vygeneruje tabulku uživatelů, druhý tabulku resetovaných hesel a třetí tabulku pro neúspěšné úlohy běžící na pozadí (tzv. jobs). Vysvětleme si migrace na souboru 2014_10_12_000000_create_users_table.php, jehož obsah je následující:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}

Každá migrace se skládá ze dvou metod: up() a down():

  • Metoda up() slouží ke změně databázové tabulky (například přidání nového sloupečku nebo klíče).
  • Metoda down() je přesným opakem metody up(). Bude zavolaná v případě, kdy chceme změny vrátit zpátky.

Pro správu databázové struktury přes migrace používáme builder Schema. Tomu poté předáme jako parametr instanci třídy Blueprint zastupující tabulku.

Proč vlastně Laravel již v základu obsahuje tyto 3 migrace? Jak už jsem psal v úvodní lekci, Laravel je optimalizovaný pro reálné webové aplikace a kvůli tomu také obsahuje nejčastěji používané tabulky. Tím důležitějším důvodem (platí hlavně pro první 2 migrace) je však to, že si můžeme nechat vygenerovat celou část registrace a přihlašování uživatelů. To je však předmětem až dalších lekcí.

Vytváření modelu článku

Nejdříve bychom měli začít vytvářením tabulky pro budoucí model článku. Migrace si můžeme nechat vygenerovat spolu s Eloquent modely, podíváme se jaké k tomu máme možnosti. Na to použijeme v terminálu Artisan příkaz help:

php artisan help make:model

Po vložení příkazu uvidíme následující výstup:

Výstup Artisan příkazu help pro tvorbu modelů v PHP frameworku Laravel - Laravel framework pro PHP

Jak si můžeme všimnout, máme na výběr mnoho možností. Popisovat si je všechny pro nás zatím nemá význam. Většinu z nich se naučíme používat postupně. Nás budou nyní zajímat tyto dvě možnosti:

  • --resource - Vytvoří CRUD kontroler využívající instance modelu. To je kontroler pro operace k přidání, zobrazení, editaci a odstranění dané položky, v našem případě článku.
  • --migration - Vygeneruje migraci pro vytvoření tabulky modelu. Tím pro položku vytvoříme i databázovou tabulku.

Vložíme tedy následující příkaz pro vytvoření modelu článku s těmito možnostmi:

php artisan make:model --resource --migration Article

Migraci a kontroler lze vytvořit i zvlášť. Zápis výše je pouze zkrácením následujících příkazů:

php artisan make:model Article
php artisan make:migration --create=articles create_articles_table
php artisan make:controller --model=Article ArticleController

Výstup příkazu při úspěchu vypadá následovně:

Výstup Artisan příkazu pro tvorbu modelů v PHP frameworku Laravel - Laravel framework pro PHP

Jak lze vidět na obrázku výše, vygenerovaly se nám tři požadované soubory. Nejdříve začneme už zmíněnou migrací pro vytvoření tabulky článků.

Migrace tabulky článků

Určitě se shodneme na tom, že každý článek musí mít své ID, podle kterého ho budeme identifikovat např. při jeho editaci. Zároveň ale naše tabulka bude obsahovat sloupce created_at a updated_at definující časy vytvoření a poslední úpravy. Tyto sloupečky, spolu s id, jsou již jako výchozí zahrnuty v každé vygenerované tabulce. My si nyní navíc přidáme titulek, (unikátní) URL, obsah a popisek článku.

Migrační soubor pro vytvoření tabulky článků s názvem ..._create_articles_table.php, který najdeme ve složce database/migrations/, tedy upravíme do následující podoby:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateArticlesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->string('url')->unique();
            $table->string('description');
            $table->text('content');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('articles');
    }
}

Migrační soubory se pro vás můžou lišit datem v jejich názvu. Toho lze však využít v případě, kdy bychom chtěli, aby se některá z migrací provedla dřív. Pozměnili bychom pouze toto datum v názvu souboru.

Pokud databázi zatím nemáte vytvořenou, jednu si vytvořte (s názvem ze souboru .env, který je zmíněný na konci minulé lekce). Můj název pro databázi je laravel_cms.

Nyní spustíme migraci přes příkaz php artisan migrate, jehož výsledkem bude vytvoření migrační databázové tabulky, která si uchovává všechny spuštěné migrace. Dále se samozřejmě vytvoří i tabulky uživatelů, resetovaných hesel, článků a neúspěšných úloh:

Spuštění první migrace v PHP frameworku Laravel - Laravel framework pro PHP

Výstup se může lišit na základě data vytvoření daných migrací, které je reflektované v jejich názvu a které může být popřípadě upraveno.

Pokud využíváte databázi MySQL a přesto migrace nefunguje, musíme nastavit využívaný engine v DB. V souboru config/database.php upravíme řádek s názvem enginu (defaultní nastavení je null):

'mysql' => [
    'driver' => 'mysql',
    'url' => env('DATABASE_URL'),
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'unix_socket' => env('DB_SOCKET', ''),
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix' => '',
    'prefix_indexes' => true,
    'strict' => true,
    'engine' => 'InnoDB ROW_FORMAT=DYNAMIC', /* ZDE UPRAVÍME */
    'options' => extension_loaded('pdo_mysql') ? array_filter([
        PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
    ]) : [],
],

Engine máme nastavený na 'InnoDB ROW_FORMAT=DYNAMIC' a teď bychom měli schopni migraci spustit.

Model článku

Přesuneme se k modelu. Ten najdeme hned ve složce app/Models/ s názvem Article.php. Nyní obsahuje pouze vytváření třídy Article dědící z Model a použití trait třídy HasFactory. Možná vás to překvapí, ale již v této fázi je model naprosto funkční. Všechny metody, které budeme potřebovat pro práci s databází (vyhledávání, vytváření, upravování), obsahuje Model, jenž definuje právě Eloquent ORM.

Tabulku, se kterou má daný model pracovat, specifikovat nemusíme. Názvy modelů se totiž odvíjí od názvu tabulek, kdy tabulka je v množném čísle názvu dané entity a model v jednotném, protože zastupuje právě jeden záznam databázové tabulky. Pokud bychom toto z nějakého důvodu nedodržovali a chtěli jiný název tabulky, můžeme tento název definovat skrz proměnnou $table:

/**
 * The table associated with the model.
 *
 * @var string
 */
protected $table = 'articles';

Kontroler článku

Nyní se podíváme na vygenerovaný kontroler článku ve složce app/Http/Controllers/ s názvem ArticleController.php. Ten obsahuje již CRUD metody pro akce výpisu článků, vytvoření nového, editaci a odstranění:

<?php

namespace App\Http\Controllers;

use App\Models\Article;
use Illuminate\Http\Request;
use Illuminate\Http\Response;

class ArticleController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  Request $request
     * @return Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  Article $article
     * @return Response
     */
    public function show(Article $article)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  Article $article
     * @return Response
     */
    public function edit(Article $article)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  Request $request
     * @param  Article $article
     * @return Response
     */
    public function update(Request $request, Article $article)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  Article $article
     * @return Response
     */
    public function destroy(Article $article)
    {
        //
    }
}

Typicky se tyto metody používají následovně:

  • index() - Zobrazení seznamu článků (můžeme využít pro administraci)
  • create() - Zobrazení formuláře pro vytvoření článku
  • store() - Vytvoření článku z předávaných hodnot formuláře
  • show() - Zobrazení samotného článku
  • edit() - Zobrazení formuláře pro editaci článku
  • update() - Upravení databázového záznamu s článkem
  • destroy() - Odstranění článku z databáze

Využívání CRUD kontrolerů extrémně ulehčuje práci, jelikož jejich routování je daleko jednodušší a zároveň nám to přidává další možnosti v rámci práce s daným kontrolerem.

V další lekci, Jednoduchý redakční systém v Laravel - Výpis článku, si zobrazíme náš první článek. Navíc si budete moci stáhnout zdrojové kódy v případě, že jste měli s čímkoli problém :)


 

Měl jsi s čímkoli problém? Zdrojový kód vzorové aplikace je ke stažení každých pár lekcí. Zatím pokračuj dál, a pak si svou aplikaci porovnej se vzorem a snadno oprav.

Předchozí článek
Jednoduchý redakční systém v Laravel - Struktura projektu
Všechny články v sekci
Laravel framework pro PHP
Přeskočit článek
(nedoporučujeme)
Jednoduchý redakční systém v Laravel - Výpis článku
Článek pro vás napsal Jan Lupčík
Avatar
Uživatelské hodnocení:
37 hlasů
Autor se primárně věnuje vývoji webových stránek a aplikací v PHP (framework Laravel) a je jedním z herních vývojářů komunitní modifikace TruckersMP.
Aktivity