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 metodyup()
. 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:

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ě:

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:

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ánkustore()
- Vytvoření článku z předávaných hodnot formulářeshow()
- Zobrazení samotného článkuedit()
- Zobrazení formuláře pro editaci článkuupdate()
- Upravení databázového záznamu s článkemdestroy()
- 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.