Table of contents
Bismillahirrahmanirrahim
Apakah kamu pernah merancang desain struktur database dan menemukan bahwa ada beberapa kolom yang hampir selalu ada di setiap tabelnya? Lebih memukau lagi bahwa kamu selalu menulis ulang di setiap file migration-nya? Apakah ada cara agar kamu tidak menulis ulang kolom-kolom tersebut di hampir setiap file migration yang ada?
Studi Kasus
Misalnya saya selalu ingin memasukkan beberapa kolom ini:
created_by
updated_by
deleted_by
created_at
updated_at
deleted_at
Maka di setiap file migration harus selalu ada baris ini:
$table->string('created_by', 150)->nullable()->default('Sistem');
$table->string('updated_by', 150)->nullable()->default('Sistem');
$table->string('deleted_by', 150)->nullable();
$table->timestamps();
$table->softDeletes();
Sudah terbayang bagaimana repotnya untuk melakukan copy-paste setiap menambah file migration baru?
Solusi
Ada 2 cara yang saya tau untuk menangani masalah perulangan di atas, antara lain:
Lewat file AppServiceProvider.php yang terdapat di folder app/Providers.
Menggunakan Trait.
Keduanya tetap memanfaatkan fitur Macro pada Blueprint. Pada artikel ini saya mengesampingkan teori dan lebih mengedepankan prakteknya.
Mari kita mulai ngoding!
Lewat AppServiceProvider
Dalam function boot, tambahkan kode berikut:
// Blueprint Macro
Blueprint::macro('opsFields', function () {
$this->string('created_by', 150)->nullable()->default('Sistem');
$this->string('updated_by', 150)->nullable()->default('Sistem');
$this->string('deleted_by', 150)->nullable();
$this->timestamps();
$this->softDeletes();
});
Maka jika kamu butuh kolom-kolom tersebut dalam file migration, maka cukup tambahkan saja $table->opsFields()
di dalamnya. Contohnya jadi seperti ini:
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('code', 7)->unique();
$table->string('name', 150);
$table->opsFields();
});
Menggunakan Trait
Buat sebuah class baru dengan perintah php artisan make:trait OpsFields
dan tuliskan isinya sebagai berikut:
public function opsFields(Blueprint $table): void
{
$table->string('created_by', 150)->nullable()->default('Sistem');
$table->string('updated_by', 150)->nullable()->default('Sistem');
$table->string('deleted_by', 150)->nullable();
$table->timestamps();
$table->softDeletes();
}
File trait selengkapnya jadi seperti ini:
<?php
namespace App\Traits;
use Illuminate\Database\Schema\Blueprint;
trait OpsFields
{
public function opsFields(Blueprint $table): void
{
$table->string('created_by', 150)->nullable()->default('Sistem');
$table->string('updated_by', 150)->nullable()->default('Sistem');
$table->string('deleted_by', 150)->nullable();
$table->timestamps();
$table->softDeletes();
}
}
Maka jika kamu butuh kolom-kolom tersebut dalam file migration, maka cukup tambahkan saja $table->opsFields()
di dalamnya. Contohnya jadi seperti ini:
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('code', 7)->unique();
$table->string('name', 150);
$this->opsFields($table);
});
Jangan lupa tambahkan namespace pada bagian atas file migration-nya:
use App\Traits\OpsFields;
Selengkapnya jadi seperti ini file migration-nya
<?php
use App\Traits\OpsFields;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
use OpsFields;
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('code', 7)->unique();
$table->string('name', 150);
$this->opsFields($table);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('categories');
}
};
Hasil
Jika kamu coba jalankan perintah di terminal sebagai berikut php artisan migrate --pretend
, maka akan menghasilkan query sebagai berikut:
create table `categories` (
`id` bigint unsigned not null auto_increment primary key,
`code` varchar(7) not null,
`name` varchar(150) not null,
`created_by` varchar(150) null default 'Sistem',
`updated_by` varchar(150) null default 'Sistem',
`deleted_by` varchar(150) null,
`created_at` timestamp null,
`updated_at` timestamp null,
`deleted_at` timestamp null
) default character set utf8mb4 collate 'utf8mb4_unicode_ci';
alter table `categories` add unique `categories_code_unique`(`code`);
Nah, silahkan kamu pilih mau pakai metode yang mana. Apakah lewat service provider atau trait. Pilihan saya? Trait. Mengapa?
Jika menggunakan Trait, maka ia akan hadir jika dipanggil saja. Adapun jika service provider, sejatinya ia akan selalu dipanggil di setiap request, tentang migration atau lainnya.