Laravel

Database migrations

In het voorbeeld met movies en ratings is de rating-tabel een pivot-table. Een movie kan meerdere keren een rating ontvangen van een user en een user kan op zijn beurt meerdere movies een rating geven. In de pivot-table 'ratings' wordt dit bijgehouden. Aangezien een user maar 1 keer dezelfde film een rating kan geven wordt de primaire sleutel voor de ratings-table een combinatie van het 'id' van de 'movie' en het 'id' van de 'user'. Eerst maak je een migration-file

php artisan make:migration create_ratings_table

Van de gecombineerde primaire sleutel wordt opgebouwd uit 'movie_id' en 'user_id'. Beide velden zijn ook nog eens vreemde sleutel van het 'id' in resp. de 'movie' en de user 'tabel'. In de migration moeten de volgende stappen worden genomen:

De up-methode voor deze migration ziet er nu zo uit:

    public function up()
{
Schema::create('ratings', function (Blueprint $table) {
$table->unsignedbigInteger('movie_id');
$table->unsignedbigInteger('user_id');
$table->primary(['movie_id', 'user_id']);
$table->foreign('user_id')->references('id')->on('users');
$table->foreign('movie_id')->references('id')->on('movies');
$table->smallinteger('rating');
$table->timestamps();
});
}

Seeders

Nu de tabellen zijn gecreƫerd hebben we nog een aantal records nodig om straks mee te kunnen testen. Laravel biedt hiervoor de mogelijkheid om 'seeders' aan te maken. Je kunt de tabellen vullen met data om mee te testen.

php artisan make:seeder MovieSeeder

In het bestand MovieSeeder kun je met Laravel QueryBuilder de insert-statements maken om records toe te voegen.

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class MovieSeeder extends Seeder
{
public function run()
{
DB::table('movies')->insert([
'title' => 'Tokyo Story',
'year' => 1953,
'created_at' => \Carbon\Carbon::now(),
]);
DB::table('movies')->insert([
'title' => 'Sunrise',
'year' => 1927,
'created_at' => \Carbon\Carbon::now(),
]);
}

Php artisan kan je database automatisch 'seeden' en voorzien van records. Het bestand DatabaseSeeder.php wordt hiervoor aangeroepen. Vanuit DatabaseSeeder worden alle seeders aangeroepen die je wilt activeren. Dat gebeurt met de functie call()...

    public function run()
{
$this->call([
MovieSeeder::class,
]);
}

Om de database opnieuw op te bouwen met tabellen en records.....

php artisan migrate:fresh --seed

Hetzelfde kun je doen om een aantal test-gebruikers toe te voegen....

php artisan make:seeder UserSeeder

UserSeeder.php
Users hebben standaard een wachtwoord. Wachtwoorden met behulp van hashing onherkenbaar gemaakt. Laravel maakt hiervoor gebruik van de php-functie 'bcrypt'.

    public function run()
{
DB::table('users')->insert([
'name' => 'spock',
'email' => 'spock@gmail.com',
'password' => bcrypt('password'),
'created_at' => \Carbon\Carbon::now(),
]);
DB::table('users')->insert([
'name' => 'truus',
'email' => 'truus@gmail.com',
'password' => bcrypt('1234'),
'created_at' => \Carbon\Carbon::now(),
]);
}

En nu de ratings. Ook hiervoor kun je een seeder maken. Je moet er alleen rekening mee houden dat je geen ratings aanmaakt van users of movies die niet bestaan. In dit geval is er voor gekozen om alle movies door een gebruiker een random rating te laten geven. Met 'DB::table('users')->get()' haal je alle user op uit de database.

php artisan make:seeder RatingSeeder
    public function run()
{
foreach (DB::table('users')->get() as $user) {
foreach(DB::table('movies')->get() as $movie) {
DB::table('ratings')->insert([
'user_id' => $user->id,
'movie_id' => $movie->id,
'rating' => random_int(1,5),
'created_at' => \Carbon\Carbon::now(),
]);
}
}
}

Aanpassen DatabaseSeeder

    public function run()
{
$this->call([
MovieSeeder::class,
UsersSeeder::class,
RatingSeeder::class
]);
}
php artisan migrate:fresh --seed