Cara Membuat CRUD Filament 5 di Laravel 13 Lengkap untuk Pemula
Pelajari cara membuat CRUD produk menggunakan Laravel 13 dan Filament 5, mulai dari model, migration, form tambah dan edit, tabel data, pencarian, filter, hingga fitur hapus data.
Cara Membuat CRUD Filament 5 di Laravel 13 Lengkap untuk Pemula
CRUD merupakan singkatan dari Create, Read, Update, dan Delete. Empat proses tersebut menjadi dasar dalam pembuatan aplikasi yang menggunakan database.
Pada tutorial ini, kita akan membuat CRUD produk menggunakan Laravel 13 dan Filament 5. Data produk nantinya dapat ditambahkan, ditampilkan, diperbarui, dicari, difilter, dan dihapus melalui dashboard admin.
Data yang akan digunakan meliputi:
- Nama produk
- SKU produk
- Harga
- Stok
- Deskripsi
- Status aktif
- Tanggal dibuat
Setelah tutorial selesai, menu Produk akan tersedia di dashboard Filament.
Persiapan Project
Tutorial ini menganggap Laravel 13 dan Filament 5 sudah terpasang.
Pastikan Anda sudah dapat membuka dashboard Filament melalui alamat:
http://127.0.0.1:8000/adminPastikan juga akun administrator Filament sudah dibuat.
Apabila belum mempunyai akun administrator, jalankan:
php artisan make:filament-userMasukkan nama, email, dan password administrator ketika diminta.
Struktur CRUD yang Akan Dibuat
CRUD produk akan menggunakan beberapa bagian utama:
app/
├── Models/
│ └── Product.php
└── Filament/
└── Resources/
└── Products/
├── ProductResource.php
├── Pages/
│ ├── CreateProduct.php
│ ├── EditProduct.php
│ └── ListProducts.php
├── Schemas/
│ └── ProductForm.php
└── Tables/
└── ProductsTable.phpModel Product digunakan untuk berinteraksi dengan tabel produk.
ProductResource digunakan untuk menghubungkan model produk dengan halaman CRUD Filament.
ProductForm digunakan untuk mengatur form tambah dan edit produk.
ProductsTable digunakan untuk mengatur tabel daftar produk.
Langkah 1: Membuat Model dan Migration Produk
Buka terminal pada folder utama project Laravel, kemudian jalankan:
php artisan make:model Product -mPerintah tersebut akan membuat dua file:
app/Models/Product.php
database/migrations/xxxx_xx_xx_xxxxxx_create_products_table.phpHuruf dan angka pada awal nama file migration akan menyesuaikan waktu pembuatan file.
Langkah 2: Membuat Struktur Tabel Produk
Buka file migration produk di folder:
database/migrationsCari file dengan nama yang diakhiri:
create_products_table.phpUbah method up() menjadi seperti berikut:
public function up(): void
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('sku')->unique();
$table->decimal('price', 15, 2)->default(0);
$table->unsignedInteger('stock')->default(0);
$table->text('description')->nullable();
$table->boolean('is_active')->default(true);
$table->timestamps();
});
}Berikut fungsi setiap kolom:
idsebagai ID utama produk.nameuntuk menyimpan nama produk.skuuntuk menyimpan kode unik produk.priceuntuk menyimpan harga.stockuntuk menyimpan jumlah stok.descriptionuntuk menyimpan deskripsi produk.is_activeuntuk menentukan apakah produk aktif.timestampsuntuk membuatcreated_atdanupdated_at.
Setelah file migration disimpan, jalankan:
php artisan migrateApabila berhasil, tabel products akan dibuat di database.
Langkah 3: Mengatur Model Product
Buka file:
app/Models/Product.phpUbah isinya menjadi:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $fillable = [
'name',
'sku',
'price',
'stock',
'description',
'is_active',
];
protected function casts(): array
{
return [
'price' => 'decimal:2',
'stock' => 'integer',
'is_active' => 'boolean',
];
}
}Properti $fillable menentukan kolom yang boleh diisi melalui proses mass assignment.
Method casts() mengubah tipe data secara otomatis:
- Harga menjadi angka desimal.
- Stok menjadi bilangan bulat.
- Status aktif menjadi boolean.
Langkah 4: Membuat Filament Resource
Jalankan perintah berikut:
php artisan make:filament-resource ProductFilament akan membuat Resource beserta halaman CRUD produk.
Struktur yang dihasilkan kurang lebih seperti berikut:
app/Filament/Resources/Products/
├── ProductResource.php
├── Pages/
│ ├── CreateProduct.php
│ ├── EditProduct.php
│ └── ListProducts.php
├── Schemas/
│ └── ProductForm.php
└── Tables/
└── ProductsTable.phpFilament 5 memisahkan form dan tabel ke file yang berbeda agar kode Resource lebih rapi dan mudah dikelola.
Sebagai alternatif, Filament juga dapat mencoba membuat konfigurasi form dan tabel berdasarkan kolom database secara otomatis:
php artisan make:filament-resource Product --generateGunakan salah satu perintah saja. Pada tutorial ini, form dan tabel akan kita atur secara manual.
Langkah 5: Membuat Form Produk
Buka file:
app/Filament/Resources/Products/Schemas/ProductForm.phpUbah isinya menjadi:
<?php
namespace App\Filament\Resources\Products\Schemas;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Schemas\Schema;
class ProductForm
{
public static function configure(Schema $schema): Schema
{
return $schema
->components([
TextInput::make('name')
->label('Nama Produk')
->required()
->maxLength(255),
TextInput::make('sku')
->label('SKU')
->required()
->maxLength(100)
->unique(ignoreRecord: true),
TextInput::make('price')
->label('Harga')
->prefix('Rp')
->numeric()
->required()
->minValue(0)
->default(0),
TextInput::make('stock')
->label('Stok')
->integer()
->required()
->minValue(0)
->default(0),
Textarea::make('description')
->label('Deskripsi')
->rows(5)
->maxLength(5000)
->columnSpanFull(),
Toggle::make('is_active')
->label('Produk Aktif')
->default(true),
])
->columns(2);
}
}Form tersebut mempunyai beberapa aturan validasi:
- Nama produk wajib diisi.
- SKU wajib diisi dan harus unik.
- Harga harus berupa angka.
- Harga tidak boleh kurang dari nol.
- Stok harus berupa bilangan bulat.
- Stok tidak boleh kurang dari nol.
- Deskripsi bersifat opsional.
- Status produk secara default aktif.
Penggunaan:
->unique(ignoreRecord: true)membuat SKU harus unik, tetapi tetap mengabaikan data produk yang sedang diedit.
Tanpa ignoreRecord: true, SKU lama dapat dianggap duplikat ketika pengguna mengedit produk tanpa mengganti SKU.
Langkah 6: Membuat Tabel Produk
Buka file:
app/Filament/Resources/Products/Tables/ProductsTable.phpUbah isinya menjadi:
<?php
namespace App\Filament\Resources\Products\Tables;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteAction;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\TernaryFilter;
use Filament\Tables\Table;
class ProductsTable
{
public static function configure(Table $table): Table
{
return $table
->columns([
TextColumn::make('name')
->label('Nama Produk')
->searchable()
->sortable(),
TextColumn::make('sku')
->label('SKU')
->searchable()
->copyable(),
TextColumn::make('price')
->label('Harga')
->money('IDR')
->sortable(),
TextColumn::make('stock')
->label('Stok')
->numeric()
->sortable(),
IconColumn::make('is_active')
->label('Aktif')
->boolean(),
TextColumn::make('created_at')
->label('Dibuat')
->dateTime('d M Y H:i')
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
TernaryFilter::make('is_active')
->label('Status Produk')
->placeholder('Semua Produk')
->trueLabel('Produk Aktif')
->falseLabel('Produk Tidak Aktif'),
])
->recordActions([
EditAction::make(),
DeleteAction::make(),
])
->toolbarActions([
BulkActionGroup::make([
DeleteBulkAction::make(),
]),
]);
}
}Konfigurasi tersebut menghasilkan beberapa fitur:
- Pencarian berdasarkan nama produk.
- Pencarian berdasarkan SKU.
- Pengurutan nama, harga, stok, dan waktu pembuatan.
- Format harga dalam mata uang rupiah.
- Ikon status aktif.
- Filter produk aktif dan tidak aktif.
- Tombol edit.
- Tombol hapus.
- Hapus banyak data sekaligus.
- Tombol salin SKU.
- Kolom waktu pembuatan yang dapat ditampilkan atau disembunyikan.
Langkah 7: Memeriksa ProductResource
Buka file:
app/Filament/Resources/Products/ProductResource.phpPastikan Resource menggunakan model Product, ProductForm, dan ProductsTable.
Isinya kurang lebih seperti berikut:
<?php
namespace App\Filament\Resources\Products;
use App\Filament\Resources\Products\Pages\CreateProduct;
use App\Filament\Resources\Products\Pages\EditProduct;
use App\Filament\Resources\Products\Pages\ListProducts;
use App\Filament\Resources\Products\Schemas\ProductForm;
use App\Filament\Resources\Products\Tables\ProductsTable;
use App\Models\Product;
use BackedEnum;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Tables\Table;
class ProductResource extends Resource
{
protected static ?string $model = Product::class;
protected static string | BackedEnum | null $navigationIcon =
'heroicon-o-shopping-bag';
protected static ?string $navigationLabel = 'Produk';
protected static ?string $modelLabel = 'Produk';
protected static ?string $pluralModelLabel = 'Produk';
protected static ?string $recordTitleAttribute = 'name';
public static function form(Schema $schema): Schema
{
return ProductForm::configure($schema);
}
public static function table(Table $table): Table
{
return ProductsTable::configure($table);
}
public static function getRelations(): array
{
return [];
}
public static function getPages(): array
{
return [
'index' => ListProducts::route('/'),
'create' => CreateProduct::route('/create'),
'edit' => EditProduct::route('/{record}/edit'),
];
}
}Properti berikut menentukan ikon menu:
protected static string | BackedEnum | null $navigationIcon =
'heroicon-o-shopping-bag';Label menu diubah menjadi Produk melalui:
protected static ?string $navigationLabel = 'Produk';Sedangkan:
protected static ?string $recordTitleAttribute = 'name';menjadikan nama produk sebagai identitas utama setiap record.
Langkah 8: Menjalankan Aplikasi
Bersihkan cache Laravel terlebih dahulu:
php artisan optimize:clearKemudian jalankan server:
php artisan serveBuka dashboard Filament:
http://127.0.0.1:8000/adminSetelah login, menu Produk seharusnya muncul pada sidebar.
Klik menu Produk, kemudian klik tombol untuk membuat produk baru.
Contoh data produk:
Nama Produk: Keyboard Mechanical
SKU: KEYBOARD-001
Harga: 750000
Stok: 25
Deskripsi: Keyboard mechanical dengan koneksi kabel.
Produk Aktif: YaKlik tombol simpan.
Data produk akan ditampilkan pada tabel.
Fitur Create atau Tambah Data
Untuk menambahkan produk:
- Buka menu Produk.
- Klik tombol tambah produk.
- Isi seluruh data yang diperlukan.
- Klik tombol simpan.
Filament akan memvalidasi data sebelum menyimpannya.
Apabila SKU sudah digunakan produk lain, form akan menampilkan pesan bahwa SKU tersebut tidak boleh sama.
Fitur Read atau Menampilkan Data
Semua produk akan ditampilkan dalam bentuk tabel.
Tabel dapat menampilkan:
- Nama produk
- SKU
- Harga
- Stok
- Status aktif
- Waktu pembuatan
Pengguna juga dapat mencari produk menggunakan kotak pencarian yang tersedia.
Fitur Update atau Edit Data
Untuk mengedit produk:
- Buka daftar produk.
- Cari produk yang ingin diperbarui.
- Klik tombol Edit.
- Ubah data yang diperlukan.
- Klik tombol simpan.
Data lama akan diperbarui dengan data yang baru.
Fitur Delete atau Hapus Data
Untuk menghapus satu produk, klik tombol Hapus pada baris produk.
Filament akan menampilkan konfirmasi sebelum data dihapus.
Untuk menghapus beberapa produk sekaligus:
- Centang beberapa produk.
- Buka menu bulk action.
- Pilih hapus.
- Konfirmasi penghapusan.
Gunakan fitur hapus dengan hati-hati karena data yang dihapus tidak dapat dikembalikan apabila belum menggunakan soft delete.
Menambahkan Filter Stok Habis
Selain filter status produk, kita dapat menambahkan filter untuk menampilkan produk yang stoknya habis.
Tambahkan import berikut pada ProductsTable.php:
use Filament\Tables\Filters\Filter;
use Illuminate\Database\Eloquent\Builder;Kemudian tambahkan filter ke dalam bagian filters():
Filter::make('out_of_stock')
->label('Stok Habis')
->query(
fn (Builder $query): Builder => $query->where('stock', 0)
),Bagian filter menjadi:
->filters([
TernaryFilter::make('is_active')
->label('Status Produk')
->placeholder('Semua Produk')
->trueLabel('Produk Aktif')
->falseLabel('Produk Tidak Aktif'),
Filter::make('out_of_stock')
->label('Stok Habis')
->query(
fn (Builder $query): Builder => $query->where('stock', 0)
),
])Sekarang administrator dapat menampilkan produk yang stoknya sudah habis.
Menampilkan Stok sebagai Badge
Kolom stok dapat dibuat lebih menarik dengan menambahkan badge.
Ubah kolom stok menjadi:
TextColumn::make('stock')
->label('Stok')
->numeric()
->badge()
->color(fn (int $state): string => match (true) {
$state === 0 => 'danger',
$state <= 10 => 'warning',
default => 'success',
})
->sortable(),Warna badge akan berubah berdasarkan jumlah stok:
- Merah jika stok kosong.
- Kuning jika stok 10 atau kurang.
- Hijau jika stok lebih dari 10.
Mengurutkan Produk Terbaru
Agar produk terbaru tampil paling atas, tambahkan:
->defaultSort('created_at', 'desc')Letakkan sebelum columns() atau setelah konfigurasi tabel dimulai:
return $table
->defaultSort('created_at', 'desc')
->columns([
// Daftar kolom
]);Sekarang produk yang baru ditambahkan akan tampil pada bagian paling atas.
Mengubah Jumlah Data per Halaman
Anda dapat menentukan pilihan jumlah data per halaman menggunakan:
->paginationPageOptions([10, 25, 50, 100])Contohnya:
return $table
->defaultSort('created_at', 'desc')
->paginationPageOptions([10, 25, 50, 100])
->columns([
// Daftar kolom
]);Administrator dapat memilih jumlah data yang ingin ditampilkan.
Cara Mengatasi Menu Produk Tidak Muncul
Apabila Resource Produk tidak muncul di sidebar, lakukan beberapa langkah berikut.
1. Bersihkan Cache
Jalankan:
php artisan optimize:clearKemudian restart server Laravel.
2. Periksa Lokasi Resource
Pastikan file berada di:
app/Filament/Resources/Products/ProductResource.php3. Periksa Model Product
Pastikan ProductResource menggunakan model yang benar:
protected static ?string $model = Product::class;Pastikan import model tersedia:
use App\Models\Product;4. Periksa Policy
Apabila model Product mempunyai policy, pastikan method viewAny() mengizinkan pengguna melihat Resource.
Contohnya:
public function viewAny(User $user): bool
{
return true;
}5. Periksa Panel Provider
Pastikan panel Filament melakukan discovery terhadap Resource:
->discoverResources(
in: app_path('Filament/Resources'),
for: 'App\\Filament\\Resources'
)Konfigurasi tersebut biasanya tersedia secara otomatis di file:
app/Providers/Filament/AdminPanelProvider.phpCara Mengatasi Tabel Products Tidak Ditemukan
Apabila muncul error seperti:
Table products doesn't existjalankan:
php artisan migratePeriksa juga konfigurasi database di file .env.
Contoh MySQL:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=belajar_filament
DB_USERNAME=root
DB_PASSWORD=Setelah mengubah .env, jalankan:
php artisan config:clear
php artisan migrateCara Mengatasi SKU Selalu Dianggap Duplikat
Pastikan validasi SKU menggunakan:
->unique(ignoreRecord: true)Contoh lengkap:
TextInput::make('sku')
->label('SKU')
->required()
->maxLength(100)
->unique(ignoreRecord: true)Parameter ignoreRecord: true diperlukan agar data yang sedang diedit tidak dianggap sebagai duplikat dari dirinya sendiri.
Perintah Penting yang Digunakan
Membuat model dan migration:
php artisan make:model Product -mMenjalankan migration:
php artisan migrateMembuat Filament Resource:
php artisan make:filament-resource ProductMembuat Resource secara otomatis berdasarkan database:
php artisan make:filament-resource Product --generateMembersihkan cache:
php artisan optimize:clearMenjalankan server:
php artisan serveKesimpulan
Filament 5 mempermudah pembuatan CRUD di Laravel 13. Dengan model, migration, dan satu Filament Resource, kita dapat membuat halaman pengelolaan data tanpa membangun seluruh tampilan admin dari awal.
Pada tutorial ini, kita telah berhasil membuat:
- Model Product.
- Migration tabel products.
- Form tambah produk.
- Form edit produk.
- Tabel daftar produk.
- Pencarian nama dan SKU.
- Pengurutan data.
- Filter status produk.
- Format harga rupiah.
- Fitur hapus satu data.
- Fitur hapus banyak data.
- Validasi SKU unik.
CRUD tersebut dapat dikembangkan lebih lanjut dengan menambahkan:
- Upload gambar produk.
- Kategori produk.
- Soft delete.
- Import dan export Excel.
- Manajemen supplier.
- Riwayat perubahan stok.
- Role dan permission.
- Dashboard statistik produk.