Laravel adalahs salah satu Framework PHP dengan pertumbuhan pengguna yang sangat pesat. Beberapa pendapat menyebutkan bahwa Laravel semudah Code Igniter dengan fitur yang lebih modern. Mengenai keunggulan dan kelemahan Laravel akan saya tuliskan pada tulisan yang berbeda. Tulisan kali ini kita akan membahas mengenai operasi Create-Read-Update-Delete (CRUD) sederhana dengan Laravel.

Requirement

Dalam tulisan ini beberapa hal yang perlu anda perhatikan sebelum meneruskan membaca adalah:

  1. Laravel yang digunakan dalam tulisan ini adalah Laravel 5.2
  2. Form menggunakan ekstensi laravelcollective dengan alias Html dan Form (petunjuk instalasi dan konfigurasi akan dituliskan pada tulisan berikutnya)
  3. Dalam view digunakan bootstrap 3 template
  4. Dalam contoh ini kita tidak menggunakan id increment, sehingga kita akan melakukan assign id secara manual

Penyiapan database dan Migrasi

Dalam tulisan ini diasumsikan anda belum memiliki tabel operasi. Jika sudah maka anda dapat melewatkan tahap ini. Dalam contoh ini saya akan menggunakan tabel dengan nama ref_unit. Untuk memudahkan migrasi di kemudian hari maka kita buat terlebih dahulu proses migrasi dengan menjalankan artisan dan mengeksekusi kode berikut.

php artisan migrate:make create_RefUnit_table --table=ref_unit --create

Setelah itu kita buka file yang terbentuk pada folder app/database/migrations. Kemudian Ubah file migrasi yang baru saja kita buat sebagai berikut.

// app/database/migrations/####_##_##_######_create_RefUnit_table.php

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateRefUnitTable extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('ref_unit', function(Blueprint $table)
        {
$table->integer('kd_urusan'); $table->integer('kd_bidang'); $table->integer('kd_unit'); $table->integer('nm_unit'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('ref_unit'); } }

Setelah itu anda sudah bisa melakukan migrate melalui command line anda.

php artisan migrate

Membuat Model

Walaupun ada banyak cara membuat model menggunakan artisan, namun kali ini kita akan membuat model secara manual. Dalam contoh ini kita akan membuat model di base folder App, model kita akan diberi nama RefUnit. Isi dari model adalah sebagai berikut.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class RefUnit extends Model
{
    protected $table = 'ref_unit'; //disini saya mengoverride nama tabel Laravel. Dalam laravel nama tabel adalah jamak (ditambahkan huruf s dibelakang) sedang nama model tunggual (tanpa s dibelakang)

    //secara default laravel menerapkan timestamp behavior. Untuk itu kita disable fitur ini
    //pada tabel yang tidak memerlukan penyimpanan timestamp
    public $timestamps = false;
}

Dan cukup segitu dulu, selebihnya biarkan Eloquent menghandel semuanya.

Membuat Controller

Untuk membuat controller kita bisa dengan mudah menggunakan artisan. Kali ini saya akan memberikan contoh bagaimana membuat controller dengan artisan, dan memberi contoh controller yang dibuat sendiri.

Dengan menggunakan artisan anda dapat dengan mudah menggunakan perintah berikut.

php artisan controller:make UnitorganisasiController

Namun anda juga dapat dengan mudah membuat controller seperti berikut di folder app/Http/Controllers/ dengan nama UnitorganisasiController.php.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Validator;
use Session;

class UnitorganisasiController extends Controller {

    public function index()
    {
        // Code goes here
    }

}

Mengatur Route

Perbedaan Laravel dengan beberapa framework yang pernah saya gunakan (cakePHP, Code Igniter, dan Yii) adalah jika dalam framework yang lain route dibuat secara default mengarah pada controller/modul yang ada, di Laravel kita harus mengatur sendiri setiap Route yang ada. Sehingga tiap controller dan action yang ada harus dibuat Routenya di routes/web.php.

Namun dalam contoh ini kita akan menggunakan route yang lebih sederhana, dimana kita tidak perlu menerapkan route untuk tiap action, namun hanya pada controller. Anda dapat menambahkan routes berikut pada file route anda.

//untuk unitorganisasi
Route::resource('unitorganisasi', 'UnitorganisasiController');

Route diatas akan menerapkan otomatis get dan post untuk tiap action dalam controller secara default. Namun kekurangannya anda harus mengikuti konvensi penamaan action dalam laravel sebagai berikut.

HTTP Verb Path (URL) Action (Method) Route Name
GET /unitorganisasi index unitorganisasi.index
GET /unitorganisasi/create create unitorganisasi.create
POST /unitorganisasi store unitorganisasi.store
GET /unitorganisasi/{id} show unitorganisasi.show
GET /unitorganisasi/{id}/edit edit unitorganisasi.edit
PUT/PATCH /unitorganisasi/{id} update unitorganisasi.update
DELETE /unitorganisasi/{id} destroy unitorganisasi.destroy

Nah apabila anda ingin menambahkan aksi baru, maka anda perlu menambahkan ulang secara manual. Ini merupakan salah satu hal yang saya tidak sukai dari Laravel. Namun ternyata ada cara khusus untuk mengarahkan route otomatsi ke controller. Hal ini akan kita bahas pada tulisan berikutnya.

Menampilkan Data (READ)

Bagian pertama dari aksi adalah membaca seluruh data yang ada. Halaman ini biasanya adalah halaman index. Oleh karena itu kita akan membuat action Index pada controller dan menambahkan view index pada app/Http/views/unitorganisasi/index.blade.php.

UnitorganisasiController.php 

    public function index()
    {
        // get all the data
        $unit = \App\RefUnit::all();

        
        return \View::make('unitorganisasi.index') //load the view
            ->with(['model' => $unit]); //pass parameter to view
    }

index.blade.php 

@extends('layouts.app')
@section('konten')
<div class="container">
    <a class="btn btn-xs btn-success" href="/{{ URL::to('unitorganisasi/create') }}">Tambah  Unit</a>

    <!-- will be used to show any messages -->
    @if (Session::has('message'))
        <div class="alert alert-info">{{ Session::get('message') }}</div>
    @endif

    <table class="table table-striped table-bordered">
        <thead>
            <tr>
                <td>Kd Urusan</td>
                <td>Kd Bidang</td>
                <td>Kd Unit</td>
                <td>Nama Unit</td>
                <td>Actions</td>
            </tr>
        </thead>
        <tbody>
        @foreach($model as $key => $value)
            <tr>
                <td>{{ $value->kd_urusan }}</td>
                <td>{{ $value->kd_bidang }}</td>
                <td>{{ $value->kd_unit }}</td>
                <td>{{ $value->nm_unit }}</td>
                <td>
                    <a class="btn btn-xs btn-success" href="/{{ URL::to('unitorganisasi/' . $value->kd_urusan.'.'.$value->kd_bidang.'.'.$value->kd_unit) }}">Lihat</a>
                    <a class="btn btn-xs btn-info" href="/{{ URL::to('unitorganisasi/' . $value->kd_urusan.'.'.$value->kd_bidang.'.'.$value->kd_unit . '/edit') }}">Ubah</a>

                    {{ Form::open(array('url' => 'unitorganisasi/' . $value->kd_urusan.'.'.$value->kd_bidang.'.'.$value->kd_unit, 'class' => 'pull-right')) }}
                        {{ Form::hidden('_method', 'DELETE') }}
                        {{ Form::submit('Hapus Unit', array('class' => 'btn btn-xs btn-warning')) }}
                    {{ Form::close() }}
                </td>
            </tr>
        @endforeach
        </tbody>
    </table>
</div>

@endsection

Diatas saya menggunakan blade template pada beberapa aksi seperti @extends, @section, @if, dan lain-lain. Namun sebenarnya anda dapat menggunakan html biasa jika tidak familiar dengan blade. Namun dengan blade kode anda akan lebih rapi dilihat dibandingkan dengan html.

Hal berbeda pada <td> aksi adalah pada delete button. Demi keamanan maka secara default perintah delete menggunakan methode POST, bukan GET, maka tombol delete sendiri kita buat sebagai FORM daripada link seperti tombol lainnya.

Membuat Data (CREATE)

Operasi Create melibatkan dua action pada controller, yaitu create dan store. Action create akan menampilkan form, dan action store akan memvalidasi dan menyimpan data. (dalam MVC sebenarnya tidak umum dalam memvalidasi data langsung pada Controller, hal ini dianggap kurang aman dan dapat menimbulkan pengulangan penulisan kode setiap akan memvalidasi masukan. Best Practicenya adalah validasi dilakukan di model). Untuk itu kita akan membuat terlebih dahulu form dengan nama create.php dan menambahkan action create pada controller kita.

UnitorganisasiController.php 

    public function create()
    {
        // load the create form (app/views/unitorganisasi/create.blade.php)
        return \View::make('unitorganisasi.create');
    }

create.blade.php 

@extends('layouts.app')
@section('konten')

<div class="container">

    <h1>Tambah Unit</h1>

    <!-- if there are creation errors, they will show here -->
    {{ Html::ul($errors->all()) }}

    {{ Form::open(['url' => 'unitorganisasi']) }}

        <div class="form-group">
            {{ Form::label('kd_urusan', 'Urusan') }}
            {{ Form::text('kd_urusan', NULL, ['class' => 'form-control']) }}
        </div>

        <div class="form-group">
            {{ Form::label('kd_bidang', 'Bidang') }}
            {{ Form::text('kd_bidang', NULL, ['class' => 'form-control']) }}
        </div>

        <div class="form-group">
            {{ Form::label('kd_unit', 'Kode Unit') }}
            {{ Form::text('kd_unit', NULL, ['class' => 'form-control']) }}
        </div>        

        <div class="form-group">
            {{ Form::label('nm_unit', 'Nama Unit') }}
            {{ Form::text('nm_unit', NULL, ['class' => 'form-control']) }}
        </div>

        {{ Form::submit('Simpan', ['class' => 'btn btn-primary']) }}

    {{ Form::close() }}

</div>

@endsection

Form di atas menggunakan Collective dengan alias Form.

Selanjutnya kita akan membuat action store untuk menyimpan data di atas.

UnitorganisasiController.php 

    public function store()
    {
        // validate
        // read more on validation at http://laravel.com/docs/validation
        $rules = [
            'kd_urusan'       => 'required|numeric',
            'kd_bidang'       => 'required|numeric',
            'kd_unit'       => 'required|numeric',
            'nm_unit'       => 'required',
        ];
        $validator = Validator::make(Input::all(), $rules);

        // process the login
        if ($validator->fails()) {
            return Redirect::to('unitorganisasi/create')
                ->withErrors($validator)
                ->withInput(
                    // Input::except('password') //jika kita ingin tidak mengirim error validate
                    );
        } else {
            // store
            $data = new \App\RefUnit;
            $data->kd_urusan = Input::get('kd_urusan');
            $data->kd_bidang = Input::get('kd_bidang');
            $data->kd_unit = Input::get('kd_unit');
            $data->nm_unit = Input::get('nm_unit');
            $data->save();

            // redirect
            Session::flash('message', 'Unit Berhasil Ditambahkan!');
            return Redirect::to('unitorganisasi');
        }
    }

Dan setiap operasi penyimpanan akan menyimpan data pada tabel yang ada pada model \App\RefUnit.

Mengubah Data (UPDATE)

Sama seperti simpan, operasi pada mengubah data juga melibatkan dua action controller yaitu action edit untuk form dan action update untuk storing data.

UnitorganisasiController.php 

    public function edit($id)
    {
        //karena saya menggunakan multiple primary key maka saya harus memecah id yang saya kirimkan sebelumnya.
        list($kd_urusan, $kd_bidang, $kd_unit) =  explode('.', $id);
        // Inisiasi data yang akan diubah
        $unit = \App\RefUnit::where(['kd_urusan' => $kd_urusan, 'kd_bidang' => $kd_bidang, 'kd_unit' => $kd_unit])->get();
        
        return \View::make('unitorganisasi.edit')->with(['model' => $unit, 'id' => $id]);
    }

edit.blade.php 

@extends('layouts.app')
@section('konten')

<div class="container">

    <h1>Tambah Unit</h1>

    <!-- if there are creation errors, they will show here -->
    {{ Html::ul($errors->all()) }}

    {{ Form::model($model, array('route' => array('unitorganisasi.update', $id), 'method' => 'PUT')) }}

        <div class="form-group">
            {{ Form::label('kd_urusan', 'Urusan') }}
            {{ Form::text('kd_urusan', NULL, ['class' => 'form-control']) }}
        </div>

        <div class="form-group">
            {{ Form::label('kd_bidang', 'Bidang') }}
            {{ Form::text('kd_bidang', NULL, ['class' => 'form-control']) }}
        </div>

        <div class="form-group">
            {{ Form::label('kd_unit', 'Kode Unit') }}
            {{ Form::text('kd_unit', NULL, ['class' => 'form-control']) }}
        </div>        

        <div class="form-group">
            {{ Form::label('nm_unit', 'Nama Unit') }}
            {{ Form::text('nm_unit', NULL, ['class' => 'form-control']) }}
        </div>

        {{ Form::submit('Simpan', ['class' => 'btn btn-primary']) }}

    {{ Form::close() }}

</div>

@endsection

Form di atas menggunakan Collective dengan alias Form.

Selanjutnya kita akan membuat action store untuk menyimpan data di atas.

UnitorganisasiController.php 

    public function update($id)
    {
//karena saya menggunakan multiple primary key maka saya harus memecah id yang saya kirimkan sebelumnya. list($kd_urusan, $kd_bidang, $kd_unit) = explode('.', $id);
// validate // read more on validation at http://laravel.com/docs/validation $rules = [ 'kd_urusan' => 'required|numeric', 'kd_bidang' => 'required|numeric', 'kd_unit' => 'required|numeric', 'nm_unit' => 'required', ]; $validator = Validator::make(Input::all(), $rules); // process the login if ($validator->fails()) { return Redirect::to('unitorganisasi/'.$id.'/edit') ->withErrors($validator) ->withInput( // Input::except('password') //jika kita ingin tidak mengirim error validate ); } else { // store $data = \App\RefUnit::where(['kd_urusan' => $kd_urusan, 'kd_bidang' => $kd_bidang, 'kd_unit' => $kd_unit])->get(); $data->kd_urusan = Input::get('kd_urusan'); $data->kd_bidang = Input::get('kd_bidang'); $data->kd_unit = Input::get('kd_unit'); $data->nm_unit = Input::get('nm_unit'); $data->save(); // redirect Session::flash('message', 'Unit Berhasil Ditambahkan!'); return Redirect::to('unitorganisasi'); } }

Dan setiap operasi mengubah data pada tabel yang ada pada model \App\RefUnit.

Menghapus Data (DELETE)

Laravel identik dengan melakukan koding dengan seni (artisan), maka kata-kata yang ada pun menarik, yaitu destroy(). Nah untuk menghapus data caranya sangat sederhana. Hal yang tidak boleh dilupakan adalah secara default action destroy hanya bisa digunakan dengan metode POST, jika GET maka operasi akan gagal. Berikut action controller untuk menghapus yaitu action destroy.

    public function destroy($id)
    {
        list($kd_urusan, $kd_bidang, $kd_unit) =  explode('.', $id);
        // delete
        $unit = \App\RefUnit::where(['kd_urusan' => $kd_urusan, 'kd_bidang' => $kd_bidang, 'kd_unit' => $kd_unit]);
        $unit->delete();

        // redirect
        Session::flash('message', 'Berhasil dihapus!');
        return Redirect::to('unitorganisasi');
    }

Itu tadi bagaimana cara melakukan CRUD sederhana dengan Laravel. Hal menarik dari tutorial ini adalah saya tidak menggunakan increment id, sehingga sedikit keluar dari konvensi. Disini saya mencontohkan dengan menggunakan multiple primary key (which is not an ideal practise), dengan single primary key coding akan lebih mudah. Contohnya untuk find anda cukup menggunakan \App\RefUnit::find($id). 

Itulah tadi tutorial sederhana bagaimana melakukan CRUD sederhana pada Laravel. Cukup mudah namun jika anda melakukan migrasi dari aplikasi lain menggunakan Laravel cukup pain in the ass. Sama seperti saat saya menggunakan CakePHP. Every magic of Laravel kind of doesn't work. Baiklah demikian dan Happy Coding!!!