Dag 2 - osadi/yrgo GitHub Wiki
Migrations och Modeller
Vi antar här att vi har en databas igång och att Laravel är konfigurerad att använda sig av den. Se Starta ett nytt projekt för information om hur man gör det.
Model
Vi kan enkelt skapa en modell med kommandot:
php artisan make:model XXX
Där XXX är namnet på vår modell i singular. Detta kommer att skapa upp två filer åt oss.
app\XXX.php
- 'database\migrations\Y_m_d_xxxxx_create_XXXs_table.php
Den första är vår modell, den andra är en migration.
Migrations
Vad är en migration? Det är en klass som talar om hur databasschemat ser ut i vår applikation. Den kan skapa, redigera och radera tabeller och kolumner.
Genom att använda oss av migrations så får vi spårning på förändringarna som sker i databasschemat, och det är lätt för andra utvecklare att genomföra exakt samma ändring.
Vi får även ett enkelt sätt att backa om det t.ex skulle visa sig att en ändring vi gjort introducerat fel.
Man kan se migrations som ett sätt att versionshantera sin databas.
Vi kan antingen få en migrations-fil genom att den skapas automatiskt åt oss när vi skapar en modell, eller genom att själva skapa den med ex:
php artisan make:migration create_XXXs_table --create="XXXs"
eller
php artisan make:migration alter_zzz_on_XXXs --table="XXXs"
Det är god standard att försöka beskriva vad som händer i filnamnet.
Note: Modellnamnet är i singular och tabellnamnet i plural.
Om vi öppnat och tittar i vår migration så finns där två metoder, en up(), och en down(). I up() så berättar vi vad som ska hända när vi kör migrate. Vi behöver oftast lägga till lite data här, och det gör man genom att säga ex:
$table->string('new_string')->unique();
Vi ser även vilken tabell vi redigerar i raden under up(). Ex med 'users':
Schema::table('users', function(Blueprint $table)
För att se vilka fält vi kan få hjälp med att skapa/ändra så se referensen här: Schema: Adding Columns
Det räcker dock inte att det ligger en fil i migrations, utan vi måste även applicera den på vår databas. Det gör vi genom att igen använda oss av kommandot artisan migrate:
php artisan migrate
Det som händer när vi kör detta kommandot är att artisan skapar upp tabellen migrations, om den inte redan finns. Sen kommer den att kolla i mappen database\migrations efter filer som inte redan är migrerade. Den vet vilka filer som är migrerade genom att kolla efter filnamnet i tabellen migrations.
Den tabellen kan t.ex se ut liknande detta:
2014_10_12_000000_create_users_table 1
2014_10_12_100000_create_password_resets_table 1
Är vår migration inte redan körd, så kommer metoden up() att köras på klassen, och där har vi beskrivit vad som ska hända. Antingen om vi ändrar ett kolumn-namn, ändrar en datatyp, lägger till en kolumn, eller vad det nu kan vara för förändring vi behöver göra.
Vill man backa förändringen så kan man köra:
php artisan migrate:rollback
Då kommer down() att köras på de migrations som ligger i senaste batchen. Batchen är en räknare i tabellen migrations som ökas med ett varje gång man kört :migrate.
down() bör alltså göra precis tvärtom mot vad up() gjorde.
Ett exempel på en migration för att skapa upp en tabell som ska spara användare:
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password', 60);
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('users');
}
Att använda en modell
Våra modeller ligger som standard rakt under app. Så om vi har skapat en modell som heter ex Student så har vi en fil i app\Student.php.
En modell som heter ex Student kommer att anta att tabellen som den ska använda är students. Detta för att modeller som standard antar att tabellen som den hör till är pluralversionen av sitt eget namn.
Så:
- Student -> students
- User -> users
- Person -> people
En liten gotcha ovan. People är pluralversionen av Person, men det kanske inte är helt uppenbart för oss som inte har engelska som modersmål. Vill man att modellen ska använda sig av en annan tabell går det bra att berätta det för den.
Så om vi öppnar upp vår Modell så kan vi lägga till en property:
protected $table = 'persons';
Vet vi att vi kommer att lägga till flera properties samtidigt på vår modell så kan vi även tala om för den att det är ok med:
protected $fillable = [];
Ett exempel från modellen User:
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['name', 'email', 'password'];
Vill vi labba lite med modellen. Lägga till/ändra data, radera inlägg mm så kan man använda sig av tinker som följer med Laravel. Ett exempel med en modell som heter Student, och som har kolumnerna first_name och last_name.
php artisan tinker
Psy Shell v0.4.1 (PHP 5.6.6-1+deb.sury.org~utopic+1 — cli) by Justin Hileman
>>> $student = new App\Student;
>>> $student->first_name = "Guybrush";
>>> $student->last_name = "Threepwood"
>>> $student->save();
Vill vi hämta upp en Student från databasen kan vi göra det med ex:
App\Student::all()
App\Student::find(1)
App\Student::where('last_name', 'Threepwood')->get();
Om vi la till våra fält tidigare under propertyn $fillable så kan vi sätta alla fält på en gång:
App\Student::create(['first_name' => 'Luke', 'last_name' => 'Skywalker'])
Läs mer om det här: Mass Assignment
Om man uppdaterar en modell istället för att skapa en så kan man använda sig av ::update()
på samma sätt som ::create()
.
Att använda en Model i sin Controller
För att kunna använda dig av din modell i din kontroller så behöver vi först tala om att vi vill ha tillgång till den.
Det gör vi genom att använda oss av use
. Så om vi har en kontroller som heter StudentsController
och metoderna vi anropar är index
& show
, så skulle det kunna se ut såhär:
// router.php
get('students', 'StudentsController@index');
get('students/{first_name}', 'StudentsController@show');
<?php namespace App\Http\Controllers;
// StudentsController.php
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Student; // <-- Vår Model
use Illuminate\Http\Request;
class StudentsController extends Controller {
public function index()
{
$students = Student::all();
return view('index', ['students' => $students]);
}
public function show($slug)
{
// $slug = first_name (Skywalker) från vår route. Ex /students/Skywalker
$student = Student::where(['first_name' => $slug])->first();
return view('show', ['student' => $student]);
}
}
Sen kan vi visa detta i vår vy med:
// index.blade.php
@foreach($students as $student)
{{ $student->first_name }}
{{ $student->last_name }}
@endforeach
// show.blade.php
{{ $student->first_name }}
{{ $student->last_name }}