Migration, Fitur Ajaib di Laravel

Migration, Fitur Ajaib di Laravel

Dalam mengatur schema database sebuah aplikasi yang skala kerumitannya mengengah kebawah dengan menggunakan cara biasa seperti yang kebanyakan dilakukan bukan jadi masalah yang berarti, akan tetapi bagaimana jika kedepannya aplikasi tersebut mengalami perubahan tingkat kerumitan seiring bertambahnya fitur, ditambah lagi ketika kita bekerja dengan tim, maka mengubahnya secara langsung kedalam database tidaklah direkomendasikan. Mengapa demikian? Karena perubahan tersebut tidak tercatat sebagai log, sehingga kita akan kebingungan letak perubahan yang telah dilakukan, apalagi dengan tim kamu.

Laravel hadir dengan menawarkan sebuah fitur yang bernama Migration. Fitur ini, sebagaimana yang dijelaskan dalam official documentation bahwa Migration are like version control for your database, allowing your team to easily modify and share the application's database schema. Penggambaran sederhananya, dimana setiap perubahan yang dilakukan baik itu membuat table, mengubah / menambahkan field, bahkan sampai proses membuat relasi sekalipun akan dicatat lognya sehingga kita tahu letak perubahan dari schema database tersebut. Masih bingung? Pada intinya, Migration akan mengurus segala sesuatunya yang berhubungan dengan schema database.

Baca Juga: Eloquent Relations: mengurutkan data di Laravel 5

Membuat Migration

Untuk membuat Migration, kita dapat memanfaatkan fitur artisan command:

php artisan make:migration nama_migration_table

Migration yang telah di-generate akan diletakkan pada direktori database/migrations. Setiap file Migration terdapat prefix timestamp yang berfungsi untuk mengurutkan Migration yang telah dibuat. Sedangkan code yang terdapat didalam file Migration baru tersebut secara otomatis akan membuat dua buah method yang masih kosong yakni up dan down

<?php
​
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
​
class PostTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        //
    }
​
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        //
    }
}

Penjelasan: Method Up akan berisi perintah untuk memanipulasi table, meliputi: membuat, mengatur atau mengubah field yang terdapat di dalam table. Sedangkan method down bertugas sebaliknya.

Command Migration memiliki opsi --table dan --create yang dapat digunakan untuk meng-generate template dalam Migration tersebut. Mari kita coba, hapus file Migration sebelumnya yang sudah dibuat atau bisa dengan menggunakan nama Migration baru (baca: pada artikel ini, saya memilih menghapus Migration sebelumnya kemudian membuatnya kembali)

//migration untuk membuat table baru
php artisan make:migration post_table --create=posts
​
//migration untuk melakukan perubahan pada table yang sudah ada
php artisan make:migration post_table --table=posts

Apabila kita cek pada Migration yang baru saja di-generate, maka akan method up dan down tidak lagi kosong.

Baca Juga: Custom Email Template Notification Laravel

Bekerja Dengan Migration

Setelah file Migration kita buat, maka sebagaimana fungsinya kita dapat menggunakannya dalam memanipulasi schema database sekaligus mencatat setiap perubahan yang dilakukan. Buka file Migration database/migrations/xxxx_post_table.php (baca: nama file disertai prefix timestamp), kemudian lakukan perubahan pada method up dengan menambahkan dua buah field yakni: title dan content:

...
public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->increments('id');
        $table->string('title');
        $table->text('content');
        $table->timestamps();
    });
}
...

Penjelasan: Code di atas akan membuat sebuah table yang bernama posts. Perlu diketahui, di Laravel dalam memberikan nama pada sebuah table harus bersifat plural (jamak), jika mengacu pada aturan yang telah ditetapkannya, namun juga dapat bersifat singular dengan catatan kita mendefinisikan nama table yang telah ditetapkan pada Model (akan kita bahas pada materi yang berkaitan dengan Model). Lanjut, pada baris selanjutnya adalah perintah untuk membuat field dengan masing-masing tipe datanya: increments, string, text adalah tipe data sedangkan yang berada di dalam kurung adalah nama field. Adapun tipe data yang lebih lengkap dapat kamu lihat disini : Tipe Data.

Apabila schema table yang kita inginkan telah sesuai, maka untuk menjalankan Migration agar melakukan perubahan pada database dengna menggunakan command:

php artisan migrate

Catatan: Pastikan kamu telah melakukan konfigurasi database, agar Laravel terhubung ke dalam database. Jika belum, buka file .env kemudian masukkan informasi database kamu pada bagian berikut:

...
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=namadatabase
DB_USERNAME=userkamu
DB_PASSWORD=passwordkamu
...

Can't Move On With Rollback

Terkadang kita menyadari sebuah kesalahan yang dilakukan dalam struktur database pada Migration yang telah kita lakukan, maka disinilah fitur dari Migration ini kembali menunjukkan "Kebolehannya". Apabila kita mengecek ke dalam database, maka akan ditemukan sebuah table yang bernama migrations, fungsi dari table ini adalah untuk mencatat setiap migration yang telah dilakukan. Maka kita dapat melakukan rollback sesuai batch atau periode migrate yang telah dilakukan. Setiap batch dapat memiliki lebih dari 1 file Migration yang tercatat. Mengapa demikian? Karena bisa saja kita membuat dan mengatur lebih dari 1 file migration kemudian melakukan migrate sekaligus.

Sebelum melakukan rollback, perhatikan struktur table berikut

Kemudian, untuk melakukan rollback, dapat menggunakan command:

php artisan migrate:rollback

Apa yang terjadi?

Mengapa table yang dihilangkan? Karena migrate yang terakhir kali kita lakukan adalah membuat table, berbeda halnya jika yang terakhir kali dilakukan adalah memodifikasi field misalnya, maka rollback yang akan terapkan adalah mengembalikan pada kondisi dimana field tersebut belum dimodifikasi.

Selain dapat melakukan rollback per batch, Rollback juga dapat dilakukan dengan kondisi step terakhir. Misalnya, kita memiliki dua buah file Migration yang berbeda batch dimana masing-masing batch memiliki banyak migration. Tentu saja, jika kita menggunakan command sebelumnya maka seluruh file dari batch terakhir akan dikembalikan pada kondisi sebelumnya. Maka Laravel menyediakan flag --step yang memungkinkan kita untuk melakukan rollback beberapa step terakhir.

Contoh:

Perhatikan gambar diatas, migration terakhir adalah membuat table posts dan jobs dimana masing-masing table tersebut berbeda batch. Apabila kita melakukan command : php artisan migrate:rollback, maka yang akan dikembalikan pada kondisi sebelumnya hanyalah batch terakhir yakni posts dan apabila kita melakukan rollback sekali lagi, maka seluruh table pada batch terakhir akan dikembalikan. Nah! Bagaimana jika hanya dua buah migration terakhir saja yang ingin kita kembalikan? Solusinya adalah gunakan flag --step:

php artisan migrate:rollback --step=2

Penjelasan: Angka 2 merupakan total step terakhir yang akan dilakukan.

Lalu, apa yang terjadi?

Table posts dan jobs telah hilang dari log migrations. Keren bukan?

Refresh & Fresh Migrate

Berbicara tentang kembali ke masa lalu kadang memiliki banyak jalan, maka selain menggunakan migrate:rollback dan migrate:rollback --step, juga dapat menggunakan migrate:refresh . Lalu, dimana letak perbedaannya?

Jika migrate:rollback berdasarkan batch terakhir dan migrate:rollback --step berdasarkan step terakhir yang telah ditetapkan, maka migrate:refresh akan melakukan rollback secara keseluruhan.

Untuk melakukan rollback secara keseluruhan, kamu dapat menggunakan command:

php artisan migrate:refresh
  
//Migrate refresh sekaligus menjalankan seed
php artisan migrate:refresh --seed

Jika migrate:refresh melakukan rollback, maka berbeda halnya dengan migrate:fresh dimana akan menghapus (drop) seluruh table yang terdapat di dalam database kemudian melakukan migrate kembali.

Manipulasi Database

Tinggalkan cara lama dalam melakukan perubahan database, sebab Migration telah menyediakan cara berinteraksi dengan database. Berikut adalah beberapa perintah yang dapat kamu gunakan sesuai peruntukannya:

//Rename table
Schema::rename('nama_table_lama', 'nama_table_baru');
​
//Hapus table
Schema::drop('nama_table');
​
//Hapus table jika ada
Schema::dropIfExists('nama_table');
​
//Rename field / column
Schema::table('nama_table', function (Blueprint $table) {
    $table->renameColumn('nama_lama', 'nama_baru');
});
​
//Menghapus field
Schema::table('nama_table', function (Blueprint $table) {
    $table->dropColumn('nama_field');
  
    //Juga mendukung multiple coloum (array type)
    $table->dropColumn(['field_1', 'field_2', 'field_3']);
});
​
//Membuat index
$table->unique('nama_field');

Selain table, field juga dapat dimodifikasi sesuai keinginan. Misalnya saja, saat proses development sedang berjalan tiba-tiba kita ingin menambahkan, mengubah atau menghapus sebuah field di dalam table maka migration dapat melakukannya dengan mudah. Namun sebelumnya, install package berikut:

composer require doctrine/dbal

Case yang akan kita angkat adalah memodifikasi table posts, adapun perubahan yang akan kita lakukan diantaranya:

  1. Menambahkan field slug setelah title

  2. Mengubah field content menjadi nullable

  3. Menambahkan foreign key category_id yang nantinya akan berelasi dengan table categories

Langkah pertama, buat dua buah file migration baru:

//modifikasi table posts
php artisan make:migration modifikasi_posts_table
​
//buat table categories
php artisan make:migration categories_table --create=categories

Buka file migration database/migrations/xxxx_modifikasi_posts_table.php kemudian lakukan perubahan menjadi seperti berikut:

...
public function up()
{
   Schema::table('posts', function(Blueprint $table) {
      $table->integer('category_id')->after('id');
      $table->string('slug')->after('title');
      $table->text('content')->nullable()->change();
   });
}
​
public function down()
{
  Schema::table('posts', function($table) {
    $table->dropColumn('category_id');
    $table->dropColumn('slug');
  });
}
...

Penjelasan: Method up akan menambahkan dua buah field: category_id setelah column id dan slug setelah column title. Adapun field content dimodifikasi menjadi nullable. Sedangkan method down akan menghapus column slug dan category_id.

Pada file migration yang kedua database/migrations/xxx_categories_table.php buat field title dan descriptions misalnya.

public function up()
{
    Schema::create('categories', function (Blueprint $table) {
       $table->increments('id');
       $table->string('title');
       $table->text('descriptions');
       $table->timestamps();
    });
}

Jangan lupa untuk menjalan command:

php artisan migrate

Point terakhir adalah membuat relasi antara table posts dan categories. Buat file migration baru dengan command:

php artisan make:migration relasi_posts_categories_table

Kemudian buka file database/migrations/xxx_relasi_posts_categories_table, lalu modifikasi method up dan down

public function up()
{
    Schema::table('posts', function (Blueprint $table) {
        $table->integer('category_id')->unsigned()->change();
        $table->foreign('category_id')->references('id')->on('categories')
            ->onUpdate('cascade')->onDelete('cascade');
    });
}
​
​
public function down()
{
    Schema::table('posts', function(Blueprint $table) {
        $table->dropForeign('posts_category_id_foreign');
    });
​
    Schema::table('posts', function(Blueprint $table) {
        $table->dropIndex('posts_category_id_foreign');
    });
​
    Schema::table('posts', function(Blueprint $table) {
        $table->integer('category_id')->change();
    });
}

Penjelasan: Method up berisi code yang akan mengatur category_id menjadi foreign key yang akan terhubung dengan table categories dengan event cascade. Sedangkan method down berisi code yang akan menghapus foreign key, index dan menge-set kembali tipe data dari category_id.

Kemudian jalankan kembali command migrate, dan secara otomatis relasi antar table telah dibuat.

Baca Juga: Mudahnya Membuat Queue Mail di Laravel

Kesimpulan

Migration memiliki peranan penting dalam me-manage schema database, sehingga kamu tidak perlu repot lagi memikirkan perubahan apa yang telah dilakukan baik oleh kamu sendiri maupun oleh tim kamu.

Category:
Share:

Comments