LaravelEloquentKonvensiMenengah4 mnt baca

Konvensi Model: Nama Tabel dan Key

Pahami konvensi penamaan Laravel dan cara meng-override-nya.

Konsep: Convention over Configuration

Framework lama memaksamu menulis konfigurasi untuk segalanya: model Post pakai tabel apa? Primary key-nya kolom apa? Laravel membalik filosofinya: kalau kamu mengikuti konvensi penamaan, tidak perlu konfigurasi sama sekali. Model Post otomatis memakai tabel posts dengan primary key id. Nol baris konfigurasi.

Ini bukan sulap, cuma aturan yang konsisten: model singular PascalCase (UserProfile), tabel plural snake_case (user_profiles), primary key id, dan kolom created_at/updated_at otomatis dikelola.

Contoh 1: Konvensi Bawaan

ModelTabelPrimary Key
Postpostsid
Categorycategoriesid
UserProfileuser_profilesid

File: app/Models/Category.php

php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    // tidak perlu properti apa pun:
    // tabel 'categories', PK 'id', timestamps aktif
}

Migration pasangannya mengikuti konvensi yang sama:

File: database/migrations/2026_10_08_140000_create_categories_table.php

php
return new class extends Migration {
    public function up(): void
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->id();            // PK 'id', auto-increment
            $table->string('name');
            $table->timestamps();    // created_at + updated_at
        });
    }
    // ...
};

Selama kamu mengikuti pola ini, Eloquent "tahu" segalanya tanpa diberi tahu.

Contoh 2: Override untuk Tabel Legacy

Kadang kamu mewarisi database lama yang tidak mengikuti konvensi, misal tabel tbl_berita dengan PK id_berita (string, bukan auto-increment) dan tanpa timestamps:

File: app/Models/Berita.php

php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Berita extends Model
{
    protected $table = 'tbl_berita';   // tabel tidak mengikuti konvensi
    protected $primaryKey = 'id_berita'; // PK bukan 'id'
    public $incrementing = false;       // PK bukan auto-increment
    protected $keyType = 'string';      // PK berupa string
    public $timestamps = false;         // tanpa created_at/updated_at
}

Satu lagi yang wajib di setiap model baru: $fillable, daftar kolom yang boleh diisi massal (detail penuh di modul mass-assignment):

php
protected $fillable = ['title', 'body', 'published_at'];

Tanpa ini, Post::create([...]) melempar MassAssignmentException. Ini fitur keamanan, bukan bug.

Jebakan Umum

1. Override yang tidak lengkap. Menyetel protected $primaryKey = 'id_berita' tapi lupa public $timestamps = false padahal tabel tidak punya created_at. Hasilnya setiap save() error karena kolom tidak ada. Kalau override satu, cek semua asumsi konvensi yang dilanggar tabelmu.

2. $keyType dan $incrementing tidak sinkron. PK string (UUID) tapi $incrementing masih true: Laravel menganggap PK berupa integer auto-increment dan merusak nilai UUID saat insert. Keduanya harus disetel berpasangan.

3. Melawan konvensi tanpa alasan. Membuat tabel data_post untuk model Post "biar keren" hanya menambah satu baris $table yang harus diingat seluruh tim selamanya. Ikuti konvensi kecuali ada alasan nyata (seperti tabel legacy). Setiap override adalah utang pengetahuan.

Catatan teknis: Konvensi juga berlaku untuk foreign key: user_id menunjuk ke tabel users. Method relasi seperti belongsTo memakai tebakan ini, jadi penamaan kolom yang konsisten membuat relasi Eloquent bekerja tanpa konfigurasi tambahan.

Tantangan

Model Legacy

Misal ada tabel legacy tbl_berita dengan PK id_berita (bukan auto-increment) dan tanpa timestamps. Tulis model Berita yang benar dengan semua override yang diperlukan.

Kuis Bab

Uji pemahamanmu: Bab 4: Migration dan Seeder

Jawab 5 soal berikut, lalu tekan "Periksa Jawaban".

1.Apa fungsi method down() di migration?

2.Perintah untuk membatalkan migration batch terakhir?

3.Kenapa migrate:fresh berbahaya di production?

4.Apa kegunaan Factory dibanding Seeder manual?

5.Model Post secara konvensi memakai tabel apa?