6. diel - Jednoduchý redakčný systém v Laravel - Migrácia
V minulej lekcii, Jednoduchý redakčný systém v Laravel - Štruktúra projektu , sme si popísali štruktúru Laravel aplikácie a vytvorili si nový projekt. V dnešnom PHP tutoriálu si vysvetlíme, čo sú to migrácie, a vytvoríme si tiež svoju vlastnú.
Databázy
Údaje na pripojenie k databáze sme si nastavili v minulej lekcii. O samotnej pripojenia sa však starať nemusíme - to za nás rieši framework na pozadí. Pre prácu s databázou budeme používať Eloquent ORM, kedy každá databázová tabuľka má vlastný model (triedu) a skrz tento model pracujeme s danou tabuľkou. Ako sa ale spravuje databázová štruktúra v Laravel frameworku?
Generovanie databázové štruktúry
Predstavme si situáciu, keď pracujeme s niekým na našom projekte a následne potrebujeme zmeniť stĺpček v databázovej tabuľke. Ako tohto elegantne dosiahnuť? Jedným z riešení je zdieľať MySQL kód tejto zmeny s ďalšími vývojármi danej aplikácie. To je však veľmi neefektívne a nespoľahlivé. Pri nahrávaní zmien na produkčný server sa môže na niektoré časti MySQL kódu zabudnúť a to by spôsobilo nefunkčnosť aplikácie. Lenže takáto situácia nesmie nastať u reálne aplikácie, zákazník by asi nebol veľmi spokojný Z tohto a ďalších dôvodov vznikli migrácie.
Migrácia sú niečo ako verzia databázy. Modifikujeme skrz ne databázovú štruktúru pomocou PHP kódu cez builder alebo spúšťaním MySQL príkazov. Výhodou migráciou je, že sa vykonajú iba raz. Navyše sa v nich môžeme vracať späť, čo sa hodí, ak urobíme nejakú chybu pri vývoji.
Migrácia nájdeme v zložke database/migrations/
a pokiaľ si
túto zložku teraz otvoríme, zistíme, že už obsahuje 3 súbory. Jeden nám
vygeneruje tabuľku užívateľov, druhý tabuľku resetovaných hesiel a tretí
tabuľku pre neúspešné úlohy bežiace na pozadí (tzv. Jobs). Vysvetlime si
migrácia na súbore
2014_10_12_100000_create_password_resets_table.php
, ktorého obsah
je nasledovné:
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreatePasswordResetsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('password_resets', function (Blueprint $table) { $table->string('email')->index(); $table->string('token'); $table->timestamp('created_at')->nullable(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('password_resets'); } }
Každá migrácia sa skladá z dvoch metód: up()
a
down()
:
- Metóda
up()
slúži na zmenu databázovej tabuľky (napríklad pridanie nového stĺpčeku alebo kľúče), - zatiaľ čo metóda
down()
je jej presným opakom a bude zavolanie v prípade, že budeme chcieť vrátiť zmeny späť.
Pre správu databázové štruktúry cez migrácie používame builder
Schema
. Tomu potom odovzdáme ako parameter inštanciu triedy
Blueprint
zastupujúci tabuľku.
Prečo vlastne Laravel už v základe obsahuje tieto 3 migrácie? Ako som už písal v úvodnej lekcii, Laravel je optimalizovaný pre reálne webové aplikácie a kvôli tomu tiež obsahuje najčastejšie používané tabuľky. Tým dôležitejším dôvodom (platí hlavne pre prvé 2 migrácie) je však to, že si môžeme nechať vygenerovať celú časť registrácie a prihlasovanie užívateľov. To je však predmetom až ďalších lekcií.
Vytváranie modelu článku
Najskôr by sme mali začať vyváraním tabuľky pre budúci model článku.
Migrácia si môžeme nechať vygenerovať spolu s Eloquent modelmi, pozrieme sa
aké k tomu máme možnosti. Na to použijeme v termináli Artisan príkaz
help
:
php artisan help make:model
Po vložení príkazu uvidíme nasledujúci výstup:
Ako si môžeme všimnúť, máme na výber veľa možností. Popisovať si ich všetky pre nás zatiaľ nemá význam. Väčšinu z nich sa naučíme používať postupne. Nás budú teraz zaujímať tieto dve možnosti:
--resource
- Vytvorí CRUD kontrolér využívajúce inštancie modelu. To je kontrolér pre operácie na pridanie, zobrazenie, editáciu a odstránenie danej položky, v našom prípade článku.--migration
- Vygeneruje migráciu pre vytvorenie tabuľky modelu. Tým pre položku vytvoríme aj databázovú tabuľku.
Vložíme teda nasledujúci príkaz pre vytvorenie modelu článku s týmito možnosťami:
php artisan make:model --resource --migration Article
Migráciu a kontrolér možno vytvoriť aj zvlášť. Zápis vyššie je len skrátením nasledujúcich príkazov:
php artisan make:model Article php artisan make:migration --table=articles create_articles_table php artisan make:controller --model=Article ArticleController
Výstup príkazu pri úspechu vyzerá nasledovne:
Ako možno vidieť na obrázku vyššie, vygenerovali sa nám tri požadované súbory. Najskôr začneme už zmienenú migráciou pre vytvorenie tabuľky článkov.
Migrácia tabuľky článkov
Určite sa zhodneme na tom, že každý článok musí mať svoje ID, podľa
ktorého ho budeme identifikovať napr. Pri jeho editáciu. Zároveň ale naša
tabuľka bude obsahovať stĺpce created_at
a
updated_at
definujúce časy vytvorenie a posledné úpravy. Tieto
stĺpčeky, spolu s id
, sú už ako predvolené zahrnuté v každej
vygenerovanej tabuľke. My si teraz navyše pridáme titulok, (unikátne) URL,
obsah a popis článku.
Migračný súbor pre vytvorenie tabuľky článkov s názvom
..._create_articles_table.php
, ktorý nájdeme v zložke
database/migrations/
, teda upravíme do nasledujúcej 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->bigIncrements('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é súbory sa pre vás môžu líšiť dátumom v ich názve. To možno však využiť v prípade, kedy by sme chceli, aby sa niektorá z migráciou vykonala skôr. Pozmenili by sme iba tento dátum v názve súboru.
Teraz spustíme migráciu cez príkaz php artisan migrate
,
ktorého výsledkom bude vytvorenie migračnej databázovej tabuľky, ktorá si
uchováva všetky spustené migrácie. Ďalej sa samozrejme vytvorí aj tabuľky
užívateľov, resetovaných hesiel, článkov a neúspešných úloh:
Výstup sa môže líšiť na základe dátumu vytvorenia daných migráciou, ktoré je reflektovaná v ich názve a ktoré môže byť prípadne upraviť. Preto sa migrácie s článkami vykoná skôr ako migrácie s tabuľkou pre neúspešné úlohy.
Model článku
Presunieme sa k modelu. Ten nájdeme hneď v priečinku app/
s
názvom Article.php
. Teraz obsahuje iba vytváranie triedy
Article
dedičov z Model
. Možno vás to prekvapí,
ale už v tejto fáze je model úplne funkčné. Všetky metódy, ktoré budeme
potrebovať pre prácu s databázou (vyhľadávanie, vytváranie, upravovanie),
obsahuje Model
, ktorý definuje práve Eloquent ORM.
Tabuľku, s ktorou má daný model pracovať, špecifikovať
nemusíme. Názvy modelov sa totiž odvíja od názvu tabuliek, kedy tabuľka je
v množnom čísle názve danej entity a model v jednotnom, pretože zastupuje
práve jeden riadok databázovej tabuľky. Ak by sme toto z nejakého dôvodu
nedodržiavali a chceli iný názov tabuľky, môžeme tento názov definovať
skrz premennú $table
:
/** * The table associated with the model. * * @var string */ protected $table = 'articles';
Kontrolér článku
Teraz sa pozrieme na vygenerovaný kontrolér článku v priečinku
app/Http/Controllers/
s názvom ArticleController.php
.
Ten obsahuje už CRUD metódy pre akcie výpisu článkov, vytvorenie nového,
editáciu a odstránenie:
<?php namespace App\Http\Controllers; use App\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 sa tieto metódy používajú nasledovne:
index()
- Zobrazenie zoznamu článkov (môžeme využiť pre administráciu)create()
- Zobrazenie formuláre pre vytvorenie článkustore()
- Vytvorenie článku z odovzdávaných hodnôt formulárashow()
- Zobrazenie samotného článkuedit()
- Zobrazenie formuláre pre editáciu článkuupdate()
- Úprava databázového záznamu s článkomdestroy()
- Odstránenie článku z databázy
Využívanie CRUD kontrolerov extrémne uľahčuje prácu, pretože ich routovanie je ďaleko jednoduchšie a zároveň nám to pridáva ďalšie možnosti v rámci práce s daným kontrolerom. Tomu sa však budeme venovať až v budúcej lekcii, Jednoduchý redakčný systém v Laravel - Výpis článku , kde si zobrazíme aj náš prvý článok. Navyše si budete môcť stiahnuť zdrojové kódy v prípade, že ste mali s čímkoľvek problém