Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Migrations Laravel Blueprint Macro
#1
DRY untuk kolom-kolom tabelmu!

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:

PHP Code:
$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:

  1. Lewat file AppServiceProvider.php yang terdapat di folder app/Providers.
  2. 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:

PHP Code:
// 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:

PHP Code:
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:

PHP Code:
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 Code:
<?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:

PHP Code:
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:

PHP Code:
use App\Traits\OpsFields

Selengkapnya jadi seperti ini file migration-nya

PHP Code:
<?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:

PHP Code:
create table `categories` (
  `idbigint unsigned not null auto_increment primary key
  `codevarchar(7not null
  `namevarchar(150not null
  `created_byvarchar(150null default 'Sistem'
  `updated_byvarchar(150null default 'Sistem'
  `deleted_byvarchar(150null
  `created_attimestamp null
  `updated_attimestamp null
  `deleted_attimestamp null
) default character set utf8mb4 collate 'utf8mb4_unicode_ci';

alter table `categoriesadd 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.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)