menu

Laravel - Relation pada model (hasOne)


Hello codedoctors, kembali lagi codedoct akan share ilmu gratis.

Melanjutkan tutorial sebelumnya, kita sudah membuat sebuah relasi belongsTo pada model. Pada tutorial kali ini kita akan membuat relasi hasOne pada model, dimana pada prinsipnya relasi ini akan membuat sebuah field tabel berelasi dengan sebuah field dari tabel lain.

Tabel yang akan kita relasikan adalah tabel user dengan tabel company, oke langsung saja kita mulai tutorialnya,

Pertama, kita buat dulu tabel company-nya dengan cara php artisan migrate:make create_companies_table pada terminal atau cmd, sehingga akan otomatis membuat file migrate baru dengan nama <tanggal>_create_companies_table.php pada path protected/app/database/migrations/. Kemudian isi dengan code berikut,
<?php

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

class CreateCompaniesTable extends Migration {

 /**
  * Run the migrations.
  *
  * @return void
  */
 public function up()
 {
  Schema::create('companies', function($table){
   $table->integer('id', true);
   $table->integer('user_id')->index('companies_user_id');
   $table->string('name');
   $table->string('position');
   $table->timestamps();
  });

  Schema::table('companies', function(Blueprint $table)
        {
            $table->foreign('user_id', 'companies_ibfk_1')->references('id')->on('users')->onUpdate('CASCADE')->onDelete('CASCADE');
        });
 }

 /**
  * Reverse the migrations.
  *
  * @return void
  */
 public function down()
 {
  Schema::table('companies', function(Blueprint $table)
  {
   $table->dropForeign('companies_ibfk_1');
  });

  Schema::drop('companies');
 }

}

Kemudian, buat file seeder baru dengan nama CompanySeeder.php pada path protected/app/database/seeds/ isi dengan code berikut,
<?php
 
class CompanySeeder extends Seeder
{
    public function run()
    {
        DB::table('companies')->delete();
        DB::table('companies')->insert(array (
            array (
                'id'       => 1,
                'user_id'  => 1,
                'name'     => 'PT. HAHA',
                'position' => 'Software Engineer',
            ),
            array (
                'id'       => 2,
                'user_id'  => 2,
                'name'     => 'PT. HUHU',
                'position' => 'Marketing',
            ),
        ));
    }
}

Edit file DatabaseSeeder.php pada path protected/app/database/seeds/ dengan menambahkan seeder CompanySeeder menjadi seperti ini,
<?php

class DatabaseSeeder extends Seeder {

 /**
  * Run the database seeds.
  *
  * @return void
  */
 public function run()
 {
  // Eloquent::unguard();
  DB::statement('SET FOREIGN_KEY_CHECKS=0;');

  $this->call('UserSeeder');
  $this->call('AddressSeeder');
  $this->call('RoleSeeder');
  $this->call('CompanySeeder');

  DB::statement('SET FOREIGN_KEY_CHECKS=1;');
  \Cache::flush();
 }

}

Setelah itu edit file UserController.php pada path protected/app/controllers/relation/ menjadi seperti ini,
<?php namespace Controller\Relation;

use Model\User;
use \View;

class UserController extends \BaseController 
{
 public function getUserDetail($user_id)
 {
  $user = User::where('id', $user_id)->first();
  //code dibawah untuk panggil relasi dari model user
  if($user){
   $address = $user->addresses;
   $role = $user->role;
   $company = $user->company;
  }
  return View::make('web.relation.show-user-detail')->with('user', $user);
 }
}

Edit file model User.php dan buat file model baru dengan nama Company.php pada path protected/app/models/ sehingga code keduanya akan tampak seperti ini,
User.php

<?php namespace Model;

use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
use Illuminate\Database\Eloquent\Model;
use \Eloquent;

class User extends Eloquent implements UserInterface, RemindableInterface {

 use UserTrait, RemindableTrait;

 /**
  * The database table used by the model.
  *
  * @var string
  */
 protected $table = 'users';

 /**
  * The attributes excluded from the model's JSON form.
  *
  * @var array
  */
 protected $hidden = array('password', 'remember_token');

 // Relation
 public function addresses()
    {
        return $this->hasMany('Model\Address');
    }

    public function role()
    {
        return $this->belongsTo('Model\Role');
    }

    public function company()
    {
        return $this->hasOne('Model\Company');
    }
}

Company.php
<?php namespace Model;

class Company extends \Eloquent {

 /**
  * The database table used by the model.
  *
  * @var string
  */
 protected $table = 'companies';

 /**
  * The attributes excluded from the model's JSON form.
  *
  * @var array
  */
 protected $hidden = array('');
}

Terakhir edit file blade dengan nama show-user-detail.blade.php pada path protected/app/views/web/relation/ menjadi seperti ini,
@extends('layouts/web/master')
@section('content')
 <?php $title = "User" ?>
 <div class="isi">
  <div class="row">
   <table class="table table-bordered table-hover">
      <thead>
       <tr>
           <th>ID</th>
           <th>NAME</th>
           <th>USERNAME</th>
           <th>EMAIL</th>
        </tr>
      </thead>
      <tbody>
        <tr>
      <td>{{ $user->id }}</td>
      <td>{{ $user->name }}</td>
      <td>{{ $user->username }}</td>
      <td>{{ $user->email }}</td>
        </tr>
       </tbody>
   </table>
   <br>
   <table class="table table-bordered table-hover">
      <thead>
       <tr>
      <th>Nama alamat</th>
      <th>Kota</th>
      <th>Provinsi</th>
      <th>Alamat</th>
      <th>Zipcode</th>
      <th>Phone</th>
        </tr>
      </thead>
      <tbody>
       @forelse($user['addresses'] as $address)
         <tr>
       <td>{{ $address->name_address }}</td>
       <td>{{ $address->city }}</td>
       <td>{{ $address->province }}</td>
       <td>{{ $address->address }}</td>
       <td>{{ $address->zipcode }}</td>
       <td>{{ $address->phone }}</td>
         </tr>
        @empty
         Address not found
        @endforelse
       </tbody>
   </table>
   <br>
   <table class="table table-bordered table-hover">
      <thead>
       <tr>
      <th>Role ID</th>
      <th>Role Name</th>
        </tr>
      </thead>
      <tbody>
       @if($user['role'])
         <tr>
       <td>{{ $user['role']->id }}</td>
       <td>{{ $user['role']->name }}</td>
         </tr>
        @else
         Role not found
        @endif
       </tbody>
   </table>
   <br>
   <table class="table table-bordered table-hover">
      <thead>
       <tr>
      <th>Company Name</th>
      <th>Position</th>
        </tr>
      </thead>
      <tbody>
       @if($user['company'])
         <tr>
       <td>{{ $user['company']->name }}</td>
       <td>{{ $user['company']->position }}</td>
         </tr>
        @else
         Role not found
        @endif
       </tbody>
   </table>
  </div>
 </div>
@stop

Jangan lupa untuk mengcompile composer setelah membuat file model baru dengan cara


Sehingga tampilannya akan tampak seperti ini,


Coba cek database (phpmyadmin), saat anda menghapus salah satu field dari tabel users maka relasi tabel companies dan addresses juga ikut terhapus sedangkan field pada tabel role tidak terhapus, hal ini disebabkan karena relasi tabel companies menggunakan hasOne dan relasi tabel addresses menggunakan relasi hasMany dimana keduanya membutuhkan tabel users sebagai induknya (untuk lebih jelasnya pahamilah sendiri).

===DONE!===