Programming

Apa Itu Seeder Laravel? Fungsi, Cara Pakai & Contohnya

M
MUGHU
5 menit baca
Apa Itu Seeder Laravel? Fungsi, Cara Pakai & Contohnya
Daftar isi

Data kosong adalah salah satu hambatan paling umum saat membangun aplikasi Laravel. Tampilan tabel terlihat hampa, fitur pencarian tidak bisa diuji, dan pagination tidak pernah benar-benar terbukti bekerja karena hanya ada dua atau tiga baris data di dalam database. Laravel menyediakan jawaban resmi untuk masalah tersebut lewat fitur bernama seeder, sebuah mekanisme untuk mengisi database dengan data awal atau data dummy secara otomatis melalui satu perintah Artisan. Pembahasan berikut menguraikan pengertian seeder, cara kerjanya, hubungannya dengan factory dan Faker, hingga praktik terbaik yang biasa dipakai tim pengembang profesional.

Apa Itu Seeder pada Laravel

Seeder pada Laravel adalah sebuah class khusus yang berfungsi mengisi tabel database dengan data awal atau data dummy secara otomatis. Class ini tersimpan di direktori database/seeders dan dijalankan melalui perintah Artisan db:seed.

Istilah seeder berasal dari kata seed yang berarti benih. Analoginya sederhana: database yang baru dibuat ibarat lahan kosong, dan seeder menanam "benih" data pertama supaya lahan tersebut langsung bisa digunakan.

Setiap class seeder pada dasarnya hanya memiliki satu method bawaan, yaitu run(). Method inilah yang dipanggil ketika perintah php artisan db:seed dieksekusi, dan di dalamnya proses penyisipan data ditulis.

Isi method run() sepenuhnya fleksibel. Data bisa dimasukkan lewat query builder menggunakan facade DB, lewat Eloquent model dengan method create(), atau lewat model factory untuk menghasilkan data dalam jumlah besar.

Proses mengisi database menggunakan seeder ini sering disebut seeding. Dua istilah tersebut kerap dipakai bergantian, meski secara teknis seeder merujuk pada class-nya sedangkan seeding merujuk pada prosesnya.

Posisi Seeder dalam Alur Kerja Laravel

Laravel PHP web framework | E-SPIN Group

Seeder tidak berdiri sendiri. Fitur ini menempati satu mata rantai dalam manajemen database Laravel yang terdiri atas migration, model, factory, dan seeder.

Migration bertugas membentuk struktur tabel beserta kolomnya. Setelah struktur siap, barulah seeder mengisi tabel tersebut dengan data.

Urutan kerjanya kurang lebih seperti ini:

  1. Migration membuat atau mengubah skema tabel.

  2. Model menjembatani aplikasi dengan tabel melalui Eloquent.

  3. Factory mendefinisikan pola atau "resep" data dummy per model.

  4. Seeder menentukan kapan dan berapa banyak data dimasukkan.

Tanpa migration, seeder akan gagal karena tabel tujuannya belum ada. Tanpa seeder, aplikasi hasil migrasi tetap kosong dan sulit diuji secara realistis.

Mengapa Data Awal Perlu Dikelola Lewat Kode

Mengisi data langsung lewat phpMyAdmin atau klien database lain memang mungkin, tetapi hasilnya tidak bisa direproduksi. Begitu database di-reset, seluruh data tersebut hilang tanpa jejak.

Seeder menyimpan definisi data di dalam kode yang bisa dimasukkan ke repositori Git. Artinya, setiap anggota tim mendapatkan data awal identik hanya dengan menjalankan satu perintah.

Pendekatan ini sejalan dengan prinsip infrastructure as code. Struktur maupun isi database ikut terversi bersama kode aplikasi, sehingga perbedaan lingkungan antaranggota tim bisa ditekan.

Fungsi dan Manfaat Seeder dalam Pengembangan Aplikasi

Fungsi utama seeder adalah mengisi tabel database dengan data contoh atau data dummy tanpa proses input manual. Namun manfaat praktisnya jauh lebih luas dari sekadar hemat waktu mengetik.

Otomatisasi pengisian data menjadi keuntungan paling langsung. Ratusan bahkan ribuan baris data bisa dihasilkan dalam hitungan detik lewat satu perintah.

Konsistensi data antaranggota tim membuat proses debugging lebih mudah. Ketika seorang pengembang melaporkan bug pada halaman tertentu, rekan setimnya bisa mereproduksi kondisi yang sama karena datanya identik.

Pengujian fitur secara realistis hanya mungkin dilakukan bila datanya cukup banyak. Fitur seperti pagination, filter, sorting, dan pencarian baru terlihat kelemahannya saat berhadapan dengan data dalam jumlah besar.

Beberapa manfaat lain yang sering dirasakan pada proyek nyata:

  • Mempercepat proses onboarding pengembang baru pada sebuah proyek.

  • Menyediakan data referensi tetap seperti daftar provinsi, kategori produk, atau role pengguna.

  • Membantu proses demo aplikasi kepada klien tanpa perlu input manual.

  • Memudahkan reset database ketika kondisi data sudah berantakan akibat percobaan.

  • Menjadi fondasi data uji pada automated testing.

Dua Jenis Data yang Biasa Ditangani Seeder

Database Seeding in Laravel. Introduction | by Hossam Soliuman | Medium

Tidak semua data yang dimasukkan lewat seeder bersifat sementara. Praktik di lapangan membedakan dua kategori yang penanganannya berbeda.

Data referensi adalah data yang benar-benar dibutuhkan aplikasi agar berfungsi. Contohnya daftar role, status pesanan, kategori bawaan, satuan barang, atau akun administrator pertama.

Data dummy adalah data palsu yang hanya berguna selama pengembangan dan pengujian. Contohnya seratus pengguna acak, lima puluh artikel dengan judul random, atau transaksi fiktif untuk menguji laporan.

Aspek

Data Referensi

Data Dummy

Tujuan

Membuat aplikasi berfungsi

Menguji tampilan dan logika

Contoh

Role, kategori, akun admin

100 user acak, artikel random

Sumber nilai

Ditulis eksplisit dalam kode

Dihasilkan Faker melalui factory

Dijalankan di production

Ya, umumnya diperlukan

Tidak, harus dihindari

Sifat data

Stabil dan bermakna

Acak dan sekali pakai

Memisahkan kedua kategori ini ke dalam file seeder berbeda adalah kebiasaan yang menyelamatkan banyak proyek. Dengan pemisahan tersebut, seeder data referensi tetap aman dijalankan di server produksi tanpa ikut membawa ribuan data sampah.

Struktur Direktori dan Class Bawaan Seeder

Laravel menempatkan seluruh class seeder di dalam folder database/seeders. Struktur ini sudah tersedia sejak instalasi awal, jadi tidak perlu konfigurasi tambahan.

Di dalam folder tersebut sudah ada satu file bawaan bernama DatabaseSeeder.php. Class inilah yang secara default dijalankan ketika perintah php artisan db:seed dipanggil tanpa opsi tambahan.

Gambaran struktur folder pada proyek Laravel modern:

CODE
database/
├── factories/
│   └── UserFactory.php
├── migrations/
│   └── 0001_01_01_000000_create_users_table.php
└── seeders/
    └── DatabaseSeeder.php

DatabaseSeeder berperan sebagai pintu masuk. Class ini bisa diisi langsung dengan kode penyisipan data, tetapi praktik yang lebih rapi adalah menjadikannya orkestrator yang memanggil seeder lain.

Anatomi Sebuah Class Seeder

Setiap file seeder mengikuti pola yang sama: berada di namespace Database\Seeders, meng-extend class Illuminate\Database\Seeder, dan memiliki method run().

PHP
<?php

namespace Database\Seeders;

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

class UserSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        DB::table('users')->insert([
            'name' => 'Administrator',
            'email' => '[email protected]',
            'password' => Hash::make('password'),
        ]);
    }
}

Method run() bertipe void dan tidak menerima argumen wajib. Meski begitu, dependensi apa pun bisa di-type-hint pada signature method tersebut dan akan otomatis di-resolve oleh service container Laravel.

Satu detail penting yang sering luput: proteksi mass assignment dinonaktifkan secara otomatis selama proses seeding. Artinya, kolom yang tidak tercantum dalam properti $fillable model tetap bisa diisi lewat seeder tanpa memicu error.

Cara Membuat Seeder di Laravel Langkah demi Langkah

Membuat seeder tidak memerlukan pembuatan file manual. Laravel menyediakan perintah Artisan khusus untuk keperluan ini.

Langkah 1: Menjalankan Perintah make:seeder

Perintah dasarnya hanya satu baris di terminal, dijalankan dari direktori root proyek.

BASH
php artisan make:seeder UserSeeder

Perintah tersebut menghasilkan file baru bernama UserSeeder.php di dalam database/seeders. Penamaan class sebaiknya deskriptif dan mengikuti pola PascalCase.

Beberapa konvensi penamaan yang umum dipakai komunitas:

  • UserSeeder untuk mengisi tabel users.

  • RolesTableSeeder bila ingin menegaskan nama tabel tujuan.

  • ProductCategorySeeder untuk tabel product_categories.

  • DemoDataSeeder untuk kumpulan data demo lintas tabel.

Konsistensi lebih penting daripada memilih pola mana yang paling benar. Satu proyek sebaiknya memakai satu gaya penamaan saja.

Langkah 2: Menulis Logika di Dalam Method run

File yang baru dibuat masih memiliki method run() kosong. Isinya perlu disesuaikan dengan kebutuhan tabel yang dituju.

Pendekatan pertama memakai query builder lewat facade DB, cocok untuk penyisipan sederhana tanpa melibatkan event model.

PHP
public function run(): void
{
    DB::table('pegawai')->insert([
        'pegawai_nama' => 'Rudi',
        'pegawai_jabatan' => 'Web Designer',
        'pegawai_umur' => 25,
        'pegawai_alamat' => 'Jl. Jogja',
    ]);
}

Pendekatan kedua memakai Eloquent model, yang lebih disarankan bila model memiliki mutator, cast, atau event yang perlu ikut berjalan.

PHP
use App\Models\User;
use Illuminate\Support\Facades\Hash;

public function run(): void
{
    User::create([
        'name' => 'Admin',
        'email' => '[email protected]',
        'password' => Hash::make('password123'),
    ]);
}

Perhatikan penggunaan Hash::make() pada kolom password. Menyimpan password dalam bentuk plain text adalah kesalahan serius, bahkan pada data dummy sekalipun, karena kebiasaan tersebut mudah terbawa ke kode produksi.

Langkah 3: Menyisipkan Banyak Baris Sekaligus

Query builder mendukung penyisipan array of array untuk memasukkan beberapa baris dalam satu kali eksekusi.

PHP
DB::table('roles')->insert([
    ['name' => 'admin', 'label' => 'Administrator'],
    ['name' => 'editor', 'label' => 'Editor'],
    ['name' => 'viewer', 'label' => 'Pembaca'],
]);

Cara ini jauh lebih efisien dibanding memanggil insert() berulang kali. Satu query dikirim ke database, bukan tiga query terpisah.

Untuk data referensi yang jumlahnya puluhan, pola array seperti di atas tetap terbaca dengan baik. Bila jumlahnya sudah ratusan, memindahkan datanya ke file JSON atau CSV lalu membacanya dari seeder biasanya lebih rapi.

Cara Menjalankan Seeder Laravel

Setelah file seeder siap, eksekusinya dilakukan lewat Artisan. Ada beberapa variasi perintah dengan efek berbeda.

Menjalankan Seluruh Seeder

Perintah paling dasar menjalankan class DatabaseSeeder, yang kemudian memanggil seeder-seeder lain sesuai isinya.

BASH
php artisan db:seed

Perintah ini tidak menyentuh struktur tabel sama sekali. Data lama tetap ada, dan data baru ditambahkan di atasnya.

Menjalankan Satu Seeder Tertentu

Opsi --class memungkinkan eksekusi satu class seeder saja tanpa menjalankan yang lain.

BASH
php artisan db:seed --class=UserSeeder

Opsi ini sangat berguna saat mengembangkan seeder baru. Tidak perlu menunggu seluruh rangkaian seeder selesai hanya untuk menguji satu file.

Menggabungkan Migrasi dan Seeding

Kombinasi migrate:fresh dengan opsi --seed menghapus seluruh tabel, menjalankan ulang semua migration, lalu langsung mengisi datanya.

BASH
php artisan migrate:fresh --seed

Bila hanya satu seeder tertentu yang ingin dijalankan setelah migrasi ulang, opsi --seeder bisa ditambahkan.

BASH
php artisan migrate:fresh --seed --seeder=UserSeeder

Perintah migrate:fresh bersifat destruktif karena menghapus seluruh tabel beserta isinya. Perintah ini hanya layak dipakai di lingkungan lokal atau staging.

Perintah

Fungsi

Risiko Kehilangan Data

php artisan make:seeder NamaSeeder

Membuat file seeder baru

Tidak ada

php artisan db:seed

Menjalankan DatabaseSeeder

Rendah, hanya menambah data

php artisan db:seed --class=UserSeeder

Menjalankan satu seeder saja

Rendah

php artisan migrate --seed

Migrasi baru lalu seeding

Rendah

php artisan migrate:fresh --seed

Hapus semua tabel, migrasi ulang, seeding

Tinggi

php artisan db:seed --force

Seeding tanpa konfirmasi di production

Tinggi

Perlindungan Bawaan di Lingkungan Production

Laravel memberi lapisan pengaman ketika perintah seeding dijalankan pada environment production. Terminal akan menampilkan konfirmasi sebelum eksekusi dimulai.

Konfirmasi tersebut bisa dilewati dengan flag --force, yang biasa dipakai pada pipeline deployment otomatis.

BASH
php artisan db:seed --force

Penggunaan --force sebaiknya dibatasi hanya untuk seeder data referensi yang memang aman dijalankan berulang. Menjalankan seeder data dummy di production hampir selalu berakhir buruk.

Mengatur Banyak Seeder Lewat DatabaseSeeder

Proyek berukuran sedang biasanya memiliki lebih dari satu seeder. Menumpuk semua logika di satu file membuat kode sulit dirawat.

Solusinya adalah memecah seeder per entitas, lalu memanggilnya dari DatabaseSeeder menggunakan method call().

PHP
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeders.
     */
    public function run(): void
    {
        $this->call([
            RoleSeeder::class,
            UserSeeder::class,
            CategorySeeder::class,
            PostSeeder::class,
        ]);
    }
}

Method call() menerima array class seeder dan menjalankannya sesuai urutan penulisan. Urutan ini bukan sekadar estetika, melainkan penentu keberhasilan proses seeding.

Mengapa Urutan Pemanggilan Sangat Menentukan

Tabel yang memiliki foreign key hanya bisa diisi setelah tabel induknya terisi. Menjalankan PostSeeder sebelum UserSeeder akan memicu error constraint karena user_id yang dirujuk belum ada.

Panduan urutan yang aman:

  1. Tabel master tanpa relasi keluar, misalnya roles dan categories.

  2. Tabel utama yang bergantung pada master, misalnya users.

  3. Tabel transaksional yang bergantung pada tabel utama, misalnya posts dan orders.

  4. Tabel pivot yang menghubungkan dua tabel, misalnya role_user.

Menuliskan komentar singkat di atas array call() untuk menjelaskan alasan urutan tertentu membantu pengembang lain memahami struktur ketergantungan tanpa harus menelusuri seluruh migration.

Menonaktifkan Model Event Selama Seeding

Model Eloquent kerap memiliki event seperti creating, created, atau observer yang mengirim notifikasi. Event semacam ini sebaiknya tidak berjalan saat seeding, terutama bila memicu pengiriman email atau pemanggilan API eksternal.

Laravel menyediakan trait WithoutModelEvents untuk kebutuhan tersebut.

PHP
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;

class DatabaseSeeder extends Seeder
{
    use WithoutModelEvents;

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

Trait ini memastikan tidak ada model event yang terpicu, termasuk pada seeder lain yang dipanggil lewat method call(). Hasilnya, proses seeding berjalan lebih cepat dan bebas efek samping.

Perbedaan Seeder, Factory, dan Faker di Laravel

Tiga istilah ini sering muncul bersamaan sehingga mudah tertukar. Padahal masing-masing punya peran yang jelas berbeda.

Seeder menentukan kapan dan berapa banyak data dibuat, factory menentukan bentuk dan struktur data, sedangkan Faker menghasilkan nilai acak yang tampak realistis untuk mengisi field pada factory.

Komponen

Peran Utama

Lokasi File

Dijalankan Lewat

Seeder

Mengatur proses pengisian data

database/seeders

php artisan db:seed

Factory

Mendefinisikan pola data per model

database/factories

Dipanggil dari seeder atau test

Faker

Menghasilkan nilai acak realistis

Library pihak ketiga bawaan Laravel

Digunakan di dalam factory

Analogi dapur cukup menggambarkan hubungannya. Faker adalah bahan mentah, factory adalah resep masakan, dan seeder adalah juru masak yang memutuskan berapa porsi disajikan dan kapan.

Mengenal Faker Lebih Dekat

Faker merupakan library PHP yang menghasilkan data palsu menyerupai data nyata, seperti nama orang, alamat, email, nomor telepon, hingga paragraf teks. Library ini sudah terpasang bawaan pada instalasi Laravel, jadi tidak perlu instalasi terpisah.

Dokumentasi lengkap mengenai formatter yang tersedia bisa ditelusuri lewat dokumentasi resmi FakerPHP. Daftar formatter di sana mencakup ratusan tipe data mulai dari yang umum hingga yang sangat spesifik.

Salah satu kemampuan yang berguna untuk proyek lokal adalah dukungan lokalisasi. Faker bisa dikonfigurasi menghasilkan data khas Indonesia menggunakan locale id_ID.

PHP
use Faker\Factory as Faker;

public function run(): void
{
    $faker = Faker::create('id_ID');

    for ($i = 1; $i <= 50; $i++) {
        DB::table('pegawai')->insert([
            'pegawai_nama' => $faker->name,
            'pegawai_jabatan' => $faker->jobTitle,
            'pegawai_umur' => $faker->numberBetween(25, 40),
            'pegawai_alamat' => $faker->address,
        ]);
    }
}

Locale id_ID menghasilkan nama seperti "Bambang Wijaya" alih-alih "John Doe", serta alamat dengan format jalan dan kota Indonesia. Data seperti ini membuat tampilan aplikasi lebih meyakinkan saat didemokan kepada klien.

Perlu dicatat bahwa tidak semua formatter tersedia untuk setiap locale. Bila formatter tertentu belum diterjemahkan, Faker otomatis kembali memakai locale bawaan berbahasa Inggris.

Cara Kerja Factory di Laravel Modern

Factory tersimpan di direktori database/factories dan berbentuk class. Setiap factory memiliki method definition() yang mengembalikan array berisi aturan pembuatan data.

BASH
php artisan make:factory PostFactory --model=Post

Perintah tersebut membuat file factory yang sudah terhubung dengan model Post.

PHP
<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

class PostFactory extends Factory
{
    public function definition(): array
    {
        return [
            'title' => $this->faker->sentence(),
            'slug' => $this->faker->unique()->slug(),
            'content' => $this->faker->paragraphs(3, true),
            'is_published' => $this->faker->boolean(70),
        ];
    }
}

Pendekatan berbasis class ini menggantikan gaya lama yang memakai closure $factory->define(). Struktur class membuat factory lebih mudah dibaca, di-extend, dan dilengkapi method tambahan.

Agar model bisa memanggil factory-nya, model perlu memakai trait HasFactory.

PHP
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Post extends Model
{
    use HasFactory;
}

Memanggil Factory dari Dalam Seeder

Inilah titik pertemuan antara seeder dan factory. Seeder cukup memanggil factory dan menentukan jumlah data yang diinginkan.

PHP
use App\Models\User;

public function run(): void
{
    User::factory()->count(100)->create();
}

Satu baris tersebut menghasilkan seratus baris data pengguna lengkap dengan nama, email, dan atribut lain yang berbeda-beda. Perbandingannya dengan menulis seratus array manual sangat jauh.

Factory juga mendukung pembuatan data berelasi dalam satu rangkaian pemanggilan. Contoh membuat lima puluh pengguna yang masing-masing memiliki satu artikel:

PHP
use App\Models\User;

public function run(): void
{
    User::factory()
        ->count(50)
        ->hasPosts(1)
        ->create();
}

Method hasPosts() terbentuk otomatis berdasarkan nama relasi posts() yang didefinisikan pada model User. Pola penamaan ini mengikuti konvensi has diikuti nama relasi dalam bentuk PascalCase.

State dan Sequence untuk Variasi Data

Factory tidak hanya menghasilkan data acak seragam. Fitur state memungkinkan pembuatan varian data dengan karakteristik tertentu.

PHP
public function unpublished(): static
{
    return $this->state(fn (array $attributes) => [
        'is_published' => false,
        'published_at' => null,
    ]);
}

State tersebut kemudian dipanggil sebagai method biasa saat membuat data.

PHP
Post::factory()->count(10)->unpublished()->create();

Fitur sequence berguna ketika data perlu mengikuti pola bergiliran, misalnya separuh aktif dan separuh nonaktif. Kombinasi state dan sequence membuat skenario pengujian bisa disusun sangat spesifik tanpa menulis data satu per satu.

Kapan Sebaiknya Menggunakan Seeder

Tidak setiap situasi menuntut seeder. Memahami kapan fitur ini benar-benar memberi nilai tambah mencegah pekerjaan sia-sia.

Situasi yang Sangat Cocok Menggunakan Seeder

Awal pengembangan proyek baru adalah momen paling ideal. Membuat seeder untuk role, kategori, dan akun admin sejak hari pertama menghemat banyak waktu di kemudian hari.

Pengujian fitur berbasis daftar seperti pagination, filter, dan pencarian membutuhkan volume data yang tidak mungkin diinput manual. Seeder yang memanggil factory menyelesaikan kebutuhan ini dalam hitungan detik.

Kolaborasi tim menjadi lebih lancar karena setiap anggota bisa membangun lingkungan lokal identik. Cukup jalankan php artisan migrate:fresh --seed setelah git pull, dan database siap dipakai.

Persiapan demo kepada klien memerlukan data yang terlihat wajar. Faker dengan locale Indonesia menghasilkan nama dan alamat yang jauh lebih meyakinkan dibanding data asal ketik.

Automated testing menggunakan PHPUnit atau Pest sering membutuhkan kondisi awal tertentu. Meski factory lebih sering dipakai di konteks ini karena fleksibilitasnya, seeder tetap berguna untuk menyiapkan data referensi sebelum serangkaian test berjalan.

Situasi yang Perlu Kehati-hatian

Menjalankan seeder data dummy di server produksi hampir tidak pernah dibenarkan. Data palsu yang bercampur dengan data pelanggan nyata menimbulkan kekacauan yang mahal untuk dibersihkan.

Seeder yang tidak idempoten juga berbahaya bila dijalankan berulang. Tanpa pengecekan, eksekusi kedua akan menghasilkan duplikasi data atau error unique constraint.

Solusi untuk kasus tersebut adalah memakai updateOrCreate() atau firstOrCreate() alih-alih create().

PHP
use App\Models\Role;

public function run(): void
{
    $roles = ['admin', 'editor', 'viewer'];

    foreach ($roles as $role) {
        Role::firstOrCreate(['name' => $role]);
    }
}

Pola ini membuat seeder aman dijalankan berapa kali pun. Data yang sudah ada tidak diduplikasi, sedangkan data yang belum ada akan ditambahkan.

Praktik Terbaik Menulis Seeder yang Rapi

Seeder yang ditulis asal bisa berubah menjadi beban perawatan seiring proyek membesar. Beberapa kebiasaan berikut menjaga kualitasnya tetap terjaga.

Pisahkan Seeder Berdasarkan Tanggung Jawab

Satu file seeder sebaiknya menangani satu entitas atau satu kelompok data yang berkaitan erat. UserSeeder mengurus pengguna, CategorySeeder mengurus kategori, dan seterusnya.

Pemisahan ini memudahkan eksekusi selektif lewat opsi --class dan mempercepat proses debugging ketika ada error.

Struktur folder seeder pada proyek yang tertata biasanya terlihat seperti ini:

CODE
database/seeders/
├── DatabaseSeeder.php
├── production/
│   ├── RoleSeeder.php
│   └── SettingSeeder.php
└── development/
    ├── DemoUserSeeder.php
    └── DemoPostSeeder.php

Pemisahan folder antara data produksi dan data pengembangan mempermudah kontrol atas apa yang boleh dijalankan di mana.

Gunakan Chunking untuk Data dalam Jumlah Sangat Besar

Membuat sepuluh ribu record sekaligus lewat factory bisa memakan memori besar dan berisiko menyebabkan proses terhenti. Memecah proses menjadi beberapa batch lebih aman.

PHP
use App\Models\Product;

public function run(): void
{
    foreach (range(1, 20) as $batch) {
        Product::factory()->count(500)->create();
    }
}

Pendekatan lain untuk data statis dalam jumlah besar adalah memakai insert() langsung dengan array yang dipecah per seribu baris. Cara ini melewati Eloquent sehingga jauh lebih cepat, dengan konsekuensi timestamp dan event model harus diurus manual.

Nonaktifkan Foreign Key Check Bila Diperlukan

Beberapa skenario seeding membutuhkan penghapusan data sebelum pengisian ulang. Foreign key constraint bisa menghalangi proses truncate.

PHP
use Illuminate\Support\Facades\Schema;

public function run(): void
{
    Schema::disableForeignKeyConstraints();

    DB::table('posts')->truncate();
    DB::table('users')->truncate();

    Schema::enableForeignKeyConstraints();

    // lanjutkan proses seeding
}

Constraint wajib diaktifkan kembali setelah proses selesai. Melupakan langkah ini berpotensi meninggalkan database dalam kondisi tanpa proteksi integritas.

Manfaatkan Perintah Output untuk Memantau Proses

Seeder yang berjalan lama tanpa keluaran apa pun membuat proses terasa menggantung. Method command yang tersedia pada class Seeder bisa dipakai menampilkan pesan di terminal.

PHP
public function run(): void
{
    $this->command->info('Membuat data pengguna...');

    User::factory()->count(100)->create();

    $this->command->info('Selesai membuat 100 pengguna.');
}

Untuk proses yang sangat panjang, progress bar bawaan Artisan bisa dimanfaatkan agar durasi eksekusi lebih mudah diperkirakan.

Hindari Nilai Acak untuk Data yang Perlu Dirujuk

Data referensi seperti role atau kategori bawaan sebaiknya memakai nilai tetap, bukan hasil Faker. Nilai acak menyulitkan penulisan test yang merujuk data tersebut secara eksplisit.

Akun administrator untuk keperluan pengembangan juga sebaiknya memakai kredensial tetap yang disepakati tim. Email seperti [email protected] dengan password sederhana memudahkan setiap anggota masuk tanpa perlu bertanya.

Kesalahan Umum Saat Menggunakan Seeder dan Cara Mengatasinya

Beberapa masalah muncul berulang kali pada proyek Laravel, terutama bagi pengembang yang baru mengenal seeder.

Class Seeder Tidak Ditemukan

Pesan error Target class [UserSeeder] does not exist biasanya muncul setelah file seeder baru dibuat secara manual atau setelah struktur folder diubah.

Penyebabnya adalah autoload Composer yang belum memperbarui daftar class. Solusinya cukup menjalankan satu perintah.

BASH
composer dump-autoload

Penyebab lain adalah ketidakcocokan antara nama file dan nama class. File UserSeeder.php harus berisi class bernama UserSeeder, tanpa perbedaan huruf besar kecil.

Error Foreign Key Constraint

Pesan seperti Cannot add or update a child row: a foreign key constraint fails menunjukkan data induk belum tersedia saat data anak dimasukkan.

Perbaikannya dilakukan dengan menyusun ulang urutan pemanggilan di dalam DatabaseSeeder. Tabel induk harus selalu didahulukan.

Duplikasi Data Setelah Seeder Dijalankan Berulang

Menjalankan php artisan db:seed dua kali tanpa reset database akan menggandakan data. Bila ada kolom unique, prosesnya justru gagal dengan error integrity constraint.

Dua pendekatan bisa dipilih. Pertama, gunakan migrate:fresh --seed agar database selalu bersih sebelum diisi. Kedua, tulis seeder secara idempoten memakai firstOrCreate() atau updateOrCreate().

Password Tersimpan Tanpa Enkripsi

Kesalahan ini terjadi ketika kolom password diisi langsung dengan string biasa lewat query builder. Berbeda dengan Eloquent yang bisa memiliki cast otomatis, facade DB menyisipkan nilai apa adanya.

Penggunaan Hash::make() atau helper bcrypt() wajib dilakukan secara eksplisit. Informasi teknis mengenai algoritma hashing yang dipakai bisa ditelusuri melalui dokumentasi hashing Laravel.

Proses Seeding Berjalan Sangat Lambat

Membuat ribuan record satu per satu lewat Eloquent memicu ribuan query terpisah. Ditambah proses hashing password yang memang sengaja dibuat lambat, durasinya bisa membengkak.

Beberapa cara mempercepatnya:

  • Gunakan insert() dengan array besar alih-alih create() berulang.

  • Terapkan trait WithoutModelEvents untuk melewati observer.

  • Hindari hashing password unik per record pada data dummy, cukup pakai satu hash yang sama.

  • Bungkus proses dalam transaksi database agar commit hanya terjadi sekali.

PHP
use Illuminate\Support\Facades\DB;

public function run(): void
{
    DB::transaction(function () {
        // proses seeding di sini
    });
}

Seeder Berjalan di Environment yang Salah

Menjalankan seeder data dummy di staging yang sudah berisi data uji klien menimbulkan kebingungan. Pengecekan environment di dalam seeder mencegah kejadian tersebut.

PHP
public function run(): void
{
    if (! app()->environment('local')) {
        $this->command->warn('Seeder ini hanya untuk environment local.');
        return;
    }

    // proses seeding data dummy
}

Pengaman semacam ini murah untuk ditulis dan mahal untuk diabaikan.

Contoh Implementasi Seeder pada Kasus Nyata

Teori akan lebih mudah dicerna lewat contoh utuh. Skenario berikut menggambarkan sebuah aplikasi blog sederhana dengan tabel roles, users, categories, dan posts.

Menyiapkan Seeder Data Referensi

Role merupakan data referensi yang wajib ada agar sistem otorisasi berfungsi.

PHP
<?php

namespace Database\Seeders;

use App\Models\Role;
use Illuminate\Database\Seeder;

class RoleSeeder extends Seeder
{
    public function run(): void
    {
        $roles = [
            ['name' => 'admin', 'label' => 'Administrator'],
            ['name' => 'author', 'label' => 'Penulis'],
            ['name' => 'reader', 'label' => 'Pembaca'],
        ];

        foreach ($roles as $role) {
            Role::firstOrCreate(['name' => $role['name']], $role);
        }

        $this->command->info('Role berhasil disiapkan.');
    }
}

Penggunaan firstOrCreate() membuat seeder ini aman dijalankan kapan saja, termasuk setelah deployment ke server.

Menyiapkan Akun Administrator

Akun admin pertama biasanya dibuat lewat seeder terpisah agar kredensialnya mudah ditemukan dan diubah.

PHP
<?php

namespace Database\Seeders;

use App\Models\Role;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;

class AdminSeeder extends Seeder
{
    public function run(): void
    {
        $admin = User::updateOrCreate(
            ['email' => '[email protected]'],
            [
                'name' => 'Administrator',
                'password' => Hash::make('password'),
                'email_verified_at' => now(),
            ]
        );

        $adminRole = Role::where('name', 'admin')->first();

        if ($adminRole) {
            $admin->roles()->syncWithoutDetaching([$adminRole->id]);
        }
    }
}

Method syncWithoutDetaching() menghubungkan relasi many-to-many tanpa menghapus relasi lain yang sudah ada.

Menyiapkan Data Dummy dengan Factory

Artikel dan pengguna biasa dibuat dalam jumlah besar menggunakan factory.

PHP
<?php

namespace Database\Seeders;

use App\Models\Category;
use App\Models\Post;
use App\Models\User;
use Illuminate\Database\Seeder;

class DemoContentSeeder extends Seeder
{
    public function run(): void
    {
        if (! app()->environment('local')) {
            return;
        }

        $categories = Category::factory()->count(6)->create();

        User::factory()
            ->count(25)
            ->create()
            ->each(function ($user) use ($categories) {
                Post::factory()
                    ->count(rand(2, 8))
                    ->create([
                        'user_id' => $user->id,
                        'category_id' => $categories->random()->id,
                    ]);
            });
    }
}

Kombinasi ini menghasilkan dua puluh lima penulis dengan jumlah artikel bervariasi. Variasi seperti itu penting karena data yang terlalu seragam menyembunyikan bug pada tampilan.

Menyusun DatabaseSeeder sebagai Orkestrator

Seluruh seeder di atas kemudian dirangkai dalam satu tempat.

PHP
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;

class DatabaseSeeder extends Seeder
{
    use WithoutModelEvents;

    public function run(): void
    {
        $this->call([
            RoleSeeder::class,
            AdminSeeder::class,
            DemoContentSeeder::class,
        ]);
    }
}

Satu perintah php artisan migrate:fresh --seed kini cukup untuk membangun database lengkap dari nol.

Seeder dalam Konteks Automated Testing

Pengujian otomatis membutuhkan data dengan karakteristik berbeda dari pengembangan sehari-hari. Setiap test idealnya berjalan pada kondisi bersih dan tidak saling memengaruhi.

Factory lebih sering dipilih untuk keperluan ini karena bisa membuat data sesuai kebutuhan tiap test secara spesifik. Seeder tetap berperan menyiapkan data referensi yang dibutuhkan hampir seluruh test.

PHP
use Illuminate\Foundation\Testing\RefreshDatabase;

class PostTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();
        $this->seed(RoleSeeder::class);
    }
}

Method seed() yang tersedia di test case memungkinkan pemanggilan seeder tertentu sebelum test dijalankan. Trait RefreshDatabase memastikan database dikembalikan ke kondisi bersih setelah setiap test selesai.

Panduan lengkap mengenai pengujian di Laravel tersedia pada dokumentasi testing Laravel, termasuk pembahasan tentang database testing dan penggunaan factory di dalamnya.

Perbandingan Penggunaan Seeder dan Factory dalam Testing

Kebutuhan

Pilihan Tepat

Alasan

Data referensi tetap seperti role

Seeder

Nilainya harus konsisten dan bisa dirujuk

Data spesifik untuk satu skenario test

Factory

Bisa disesuaikan per test tanpa efek samping

Data massal untuk uji performa

Factory dalam seeder

Kombinasi jumlah besar dan pola terkontrol

Kondisi awal aplikasi sebelum seluruh test

Seeder

Cukup dijalankan sekali di setUp

Pemilihan yang tepat membuat suite pengujian berjalan lebih cepat dan hasilnya lebih dapat diandalkan.

Integrasi Seeder dengan Migration dan Alur Deployment

Seeder bekerja paling baik ketika dipadukan dengan migration dalam satu alur kerja yang konsisten.

Pada lingkungan lokal, kombinasi migrate:fresh --seed menjadi perintah harian. Struktur dan data dibangun ulang setiap kali ada perubahan skema.

Pada staging, pendekatan yang lebih hati-hati diperlukan. Migration tetap dijalankan secara inkremental dengan php artisan migrate, sedangkan seeder yang dieksekusi hanya yang berisi data referensi.

Pada produksi, seeder umumnya dijalankan sekali saat rilis pertama untuk mengisi data master. Setelah itu, perubahan data referensi biasanya dilakukan lewat migration khusus agar tercatat dalam riwayat versi.

Environment

Perintah Migration

Seeder yang Dijalankan

Frekuensi

Local

migrate:fresh --seed

Semua, termasuk data dummy

Sering, sesuai kebutuhan

Staging

migrate

Hanya data referensi

Setiap deployment

Production

migrate --force

Hanya saat rilis awal

Sekali atau sangat jarang

Pembagian ini mencegah data uji bocor ke lingkungan yang salah. Dokumentasi resmi mengenai migrasi database bisa dipelajari lebih jauh melalui halaman migration Laravel, yang menjelaskan hubungan antara skema dan proses seeding secara lebih teknis.

Menjaga Seeder Tetap Sinkron dengan Perubahan Skema

Seeder yang tidak diperbarui setelah migration berubah akan langsung gagal. Kolom baru yang bersifat NOT NULL tanpa nilai default menjadi penyebab paling umum.

Kebiasaan yang membantu adalah memperbarui seeder pada commit yang sama dengan migration terkait. Dengan begitu, riwayat perubahan tetap utuh dan rekan tim tidak menemukan database rusak setelah menarik kode terbaru.

Menjalankan php artisan migrate:fresh --seed sebelum membuat pull request juga menjadi pemeriksaan sederhana yang efektif. Bila perintah tersebut berjalan tanpa error, kemungkinan besar seeder masih selaras dengan skema terbaru.

Pertanyaan yang Sering Muncul Seputar Seeder Laravel

Apakah seeder wajib digunakan dalam setiap proyek Laravel?

Tidak wajib secara teknis, karena aplikasi tetap bisa berjalan tanpa seeder. Namun proyek yang melibatkan lebih dari satu pengembang hampir selalu diuntungkan oleh keberadaannya.

Apa perbedaan mendasar antara migration dan seeder?

Migration mengurus struktur, seeder mengurus isi. Migration membuat tabel dan kolom, sedangkan seeder memasukkan baris data ke dalam tabel yang sudah terbentuk.

Bisakah seeder dijalankan tanpa menghapus data yang sudah ada?

Bisa. Perintah php artisan db:seed hanya menambahkan data tanpa menyentuh struktur maupun data lama. Perintah yang menghapus data adalah migrate:fresh dan migrate:refresh.

Apakah factory bisa digunakan tanpa seeder?

Bisa. Factory dapat dipanggil langsung dari test case, dari Tinker, atau dari kode mana pun. Seeder hanya salah satu tempat yang umum untuk memanggilnya.

Bagaimana cara membuat data dummy berbahasa Indonesia?

Konfigurasikan Faker dengan locale id_ID, baik lewat Faker::create('id_ID') di seeder maupun dengan mengubah nilai faker_locale pada file konfigurasi aplikasi.

Apakah aman menjalankan seeder di server produksi?

Aman selama seeder yang dijalankan hanya berisi data referensi dan ditulis secara idempoten. Seeder berisi data dummy sebaiknya tidak pernah dijalankan di produksi.

Kesimpulan

Seeder pada Laravel pada akhirnya bukan sekadar cara cepat mengisi tabel, melainkan bentuk disiplin dalam mengelola data awal sebuah aplikasi. Definisi data yang tersimpan sebagai kode membuat kondisi database bisa direproduksi kapan pun, oleh siapa pun di dalam tim, hanya lewat satu perintah Artisan.

Kekuatannya terlihat jelas ketika dipadukan dengan komponen lain. Migration menyiapkan strukturnya, factory merancang pola datanya, Faker mengisinya dengan nilai yang tampak wajar, sementara seeder mengatur kapan dan berapa banyak data itu lahir. Kombinasi tersebut memangkas pekerjaan manual yang melelahkan sekaligus menjaga konsistensi antarlingkungan pengembangan.

Yang membedakan seeder biasa dengan seeder yang benar-benar berguna terletak pada detailnya. Pemisahan antara data referensi dan data dummy, urutan pemanggilan yang menghormati relasi antartabel, penulisan idempoten lewat firstOrCreate(), serta pengaman environment adalah kebiasaan kecil yang mencegah masalah besar di kemudian hari.

Langkah paling masuk akal setelah memahami konsep ini adalah langsung mempraktikkannya pada proyek yang sedang berjalan. Mulai dari satu seeder untuk data master, lalu kembangkan bertahap sambil menelusuri dokumentasi resmi Laravel untuk fitur lanjutan seperti state, sequence, dan relasi pada factory. Database yang siap pakai sejak menit pertama adalah investasi kecil dengan hasil yang terasa sepanjang umur proyek.


Referensi

BuildWithAngga. (2026). Apa itu Seeder pada Laravel.

Codepolitan. (2026). Menggunakan Seeder di Laravel.

Laravel. (2026). Database: Seeding.

BuildWithAngga. (2026). Seeder dan Factory, fitur penting Laravel yang perlu dipelajari.

Medium. (2026). Manajemen database di Laravel: Migrations, Seeders, dan Factories.

FMKelana. (2026). Pengenalan Seeder.

Medium. (2026). Laravel dasar: Seeder dan Faker pada Laravel.

Rumahweb. (2026). Belajar Laravel bagian 5: Database, Seeder dan Faker.

JogjaTech. (2026). Tutorial Laravel 12 #5: Cara menggunakan Seeder dan Factory.

SantriKoding. (2026). Laravel Inertia Spatie #4: Laravel Seeder.

Komentar (0)

Belum ada komentar. Jadilah yang pertama berbagi pendapat!

Tinggalkan komentar