Relaties tussen tabellen - Introductie
We hebben nu alles met producten gedaan. We zouden de producten in kunnen delen in categorieën. Bijvoorbeeld tuin, huishouden en gereedschap.
Tussen de beide tabellen zou dan een relatie zijn. Aan ieder product zou het id van een categorie zijn gekoppeld. Dit gaat in Laravel altijd met de naam van de andere tabel (in enkelvoud) en dan de uitbreiding _id erachter. Hier dus:
category_id
Het gebruik van deze manier van naamgeving is verplicht in Laravel. Als je dat doet dan kan Laravel automatisch allerlei relaties volgen, controleren, bewaken.
Gegevens
Hier een voorbeeld van gegevens in de beide tabellen. In de categories tabel staan gewoon nummers met namen. Dus als we het over categorie 3 hebben, dan hebben we het over kleding.
Je ziet er dat bij ieder product maar één enkele categorie hoort. In Laravel termen is dat een belongsTo.
Maar één categorie kan wel in meerdere producten worden gebruikt. De Laravel term hiervoor is hasMany.
        return $this->hasMany(Product::class);
Migreren
We hebben eerder functionaliteit gezien om database tabellen te maken. Dat gaat middels migreren. Dat gaan we nu ook weer gebruiken. De up() method tijdens de migratie van de categories table zal je nu zelf kunnen maken.
public function up(): void
{
    Schema::create('categories', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->timestamps();
    });
}
Deze tabel is niet uitgebreid. Er zit alleen een id, timestamp en een naam in.
Category_id
Als we echter vanuit products naar een categories willen wijzen is dat lastiger. We moeten dan voor products de relatie naar de id uit categories opnemen.
$table->foreignId('category_id')->constrained();
In plaats van een id maken we nu een foreignId aan. (Let op dat de 2e I een hoofdletter is). De naam van het veld is ook vastgelegd. We zijn min of meer verplicht om hiervoor de naam category_id te gebruiken. Als we dan doen, dan zal Laravel namelijk heel veel dingen voor ons gaan doen. En dat is handig.
Het opnemen van de constrained() functie vertelt Laravel dat de kolom moet verwijzen naar een bestaande tabel. Er moet dus altijd een geldige waarde instaan. Dit veld moet ook zijn gevuld.
De seeder
We maken een kleine seeder file voor categories.
DB::table('categories')->insert([
    [
        'id' => 1,
        'name' => "Juwelen",
        'created_at' => now(),
        'updated_at' => now()
    ],
    [
        'id' => 2,
        'name' => "Vervoersmiddel",
        'created_at' => now(),
        'updated_at' => now()
    ],
In de Product seeder hadden we geen waarden voor het id veld. Je ziet dat we hier wel waarden voor het id opnemen. Dat komt omdat we dadelijk uit de Product seeder moeten kunnen verwijzen naar een bepaalde categorie,
DB::table('products')->insert([
[
    'name' => "Fiets",
    'description' => "Mooie rode fiets met zijwieltjes",
    'price' => 499.99,
    'weight' => 125,
    'category_id' => 2,
    'created_at' => now(),
    'updated_at' => now()
],
Hiermee geven we dus aan dat het product fiets een categorie vervoersmiddel is.
Bij de migratie files, moet de categorie migratie worden uitgevoerd voordat de product migratie wordt uitgevoerd, anders kan de link niet worden gemaakt. En ook de seeder van category moet voor die van Product lopen, anders kunnen we het product niet koppelen aan de categorie..
Relatie notatie
Nog even over de relatie. In Eloquent termen, de database handler van Laravel is dit een relatie met de naam
products.category_id = categories.id
Deze notatie zal je zeker in foutsituaties regelmatig tegenkomen.
Relatie in het model
Het model gaat over de gegevens en de structuur ervan. Daarom moet het model ook weten wat voor een relatie dit is.
Een product hoort altijd maar bij een categorie.
Deze relatie moeten we gaan opnemen in het Product model als een belongsTo relatie. We passen het Product model aan naar onderstaande.
namespace AppModels;
use IlluminateDatabaseEloquentModel;
class Product extends Model
{
    public function category()
    {
        return $this->belongsTo(Category::class);
    }
}
In het Product model, maken we een nieuwe method aan. Deze krijgt de naam category(). Bij een product hoort een category en daar willen we naar verwijzen. In deze method zeggen we dat het product hoort bij (belongsTo())een categorie.
Vandaar de belongsTo() function. Deze geeft aan dat vanuit hier een enkele waarde is.
(Als je nog van eerder een getProducts() method had staan, dan kun je die nu weggooien.)
Model file
Om deze relatie te laten werken moet de Category model file aanwezig zijn. Er hoeft in principe niets in te staan, maar hij moet er wel zijn.
namespace AppModels;
use IlluminateDatabaseEloquentModel;
use IlluminateDatabaseEloquentRelationsBelongsTo;
class Category extends Model
{
}
Relatie terug
Ook de relatie terug kunnen we opnemen. Dan kunnen we later gaan kijken welke producten er allemaal een bepaalde categorie hebben. Opnemen doen we in het Category model.
Daar maken we een vergelijkbare method, met echter twee belangrijke verschillen.
Een categorie kan aan meerdere producten zijn gekoppeld. Daarom is de naam van de method ook products (meervoud). En is de relatie precies wat het is hasMany().
namespace AppModels;
use IlluminateDatabaseEloquentModel;
class Category extends Model
{
    public function products()
    {
Controller
In onze ProductController gaan we de methode uit het Product model meteen gebruiken. In de index() method geven we aan dat de alle Producten willen en dat we ook de relatie met category (onze naam in het model) willen.
public function index()
{
    $products = Product::with('category')->get();
    return view('product.overview',compact('products'));
}
Eerst hadden we er de functie all() staan. Omdat we nu bewerkingen op de gelezen data doen, zoals hier combineren, moeten we de get() functie gebruiken.
View
We zijn er nu bijna. We hoeven enkel nog de relatie op het scherm te zetten. Deze krijgen we binnen vanuit de controller.
In deze view kunnen we deze gemakkelijk op het scherm zetten. We geven de naam van variabel en gaan daarin ook de relatie naar categories volgen (weer met de naam category). In de categories tabel lezen we gewoon de naam.
Dit werkt precies even gemakkelijk als je zou verwachten.
<td>{{ $product->id }}</td>
<td>{{ $product->name }}</td>
<td>{{ $product->category->name }}</td>
Je ziet hier dat in een $product, we weer de naam van de relatie uit het model volgen (category) en dan het name veld (uit de categories tabel) hebben staan. Er komt hier dus de naam van de categorie welke bij het product hoort te staan.
    }
}