Press "Enter" to skip to content

Tutorial Lanjutan Relasi Table Pada Laravel Dengan Eloquent

Pada tutorial sebelumnya saya sudah membahas tentang bagaimana cara melakukan relasi table pada laravel dengan eloquent secara dasar yaitu dengan menggunakan One To Many, One To One dan Many To Many, pada tutorial kali ini saya akan melanjutkan tutorialnya dengan membahas relasi yang lebih advance yaitu Has Many Through, Polymorphic Relations dan juga Many To Many Polymorphic Relations

Relasi Table Pada Laravel Dengan Eloquent – Has Many Through

Pada relasi kali ini, kita akan membuat relasi yang menghubungkan beberapa table tanpa harus merelasikan semua table tersebut. Misalkan saya ingin menampilkan semua artikel yang berasal dari kota tertentu, hal ini bisa dilakukan tanpa harus menambah kolom kota pada artikel.

Kita hanya cukup membuat table cities dan merelasikannya dengan table users. Mari kita buat struktur tablenya

DROP TABLE IF EXISTS `cities`;
CREATE TABLE `cities` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `city_name` varchar(150) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `cities` (`id`, `city_name`, `created_at`, `updated_at`) VALUES
(1, 'Yogyakarta',   '2015-08-31 09:54:36',  '0000-00-00 00:00:00'),
(2, 'Bandung',  '2015-08-31 09:54:43',  '0000-00-00 00:00:00');

dan kita ubah table users

DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(150) NOT NULL,
  `city_id` int(11) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  KEY `city_id` (`city_id`),
  CONSTRAINT `users_ibfk_1` FOREIGN KEY (`city_id`) REFERENCES `cities` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `users` (`id`, `name`, `city_id`, `created_at`, `updated_at`) VALUES
(1, 'Dadang',   1,  '2015-08-31 09:55:33',  '0000-00-00 00:00:00'),
(2, 'Maman',    2,  '2015-08-31 09:55:38',  '0000-00-00 00:00:00');

Nah sekarang kita buat Model untuk table cities.

<?php

class City extends Eloquent {
	protected $table = 'cities';

	public function article() {
	    return $this->hasManyThrough('Article','User','city_id');
	}
}

Lalu kita modifikasi model User

<?php

class User extends Eloquent  {
	
	protected $table = 'users';

	public function articles() {
	    return $this->hasMany('Article');
	}

	public function address() {
	    return $this->hasOne('Address');
	}

	public function roles() {
	    return $this->belongsToMany('Role','role_users');
	}

	public function city() {
	    return $this->belongsTo('City');
	}

	public function comments() {
	    return $this->morphMany('Comment','commentable');
	}

	public function tags() {
            return $this->morphToMany('Tag', 'taggable');
        }
}

Setelah selesai memodifikasi Model, sekarang kita memodifikasi ArticleController.php. Tambahkan method berikut pada controller tersebut.

<?php

class ArticleController extends BaseController 
{
	// layout dengan menggunakan blade
	public $layout 	= 'layout';
	public $title  	= 'Article';

	public function index() {
		$this->layout->title = $this->title;
		/* 
		* menggunakan view yang ada 
		* pada direktori views/article/index
		*/
		$view = View::make('article.index');
		
		// query ini digunakan untuk mengambil semua data dari table article		
		$view->articles = Article::all();

		// query ini digunakan untuk menghitung total data dari table article
		$view->count = Article::all()->count();

		// render semua konten view kedalam layout
		$this->layout->content = $view;
	}

	public function city($id) {
		$this->layout->title = $this->title;
		/* 
		* menggunakan view yang ada 
		* pada direktori views/article/city
		*/
		$view = View::make('article.city');
		
		// query ini digunakan untuk mengambil semua data dari table article		
		$view->city = City::find($id);
		// render semua konten view kedalam layout
		$this->layout->content = $view;
	}	
}

Lalu kita buat 1 halaman views untuk menampilkan artikel berdasarkan kota. Buat file bernama city.blade.php di dalam direktori app/views/article.

city.blade.php

<div class="row">
  <div class="col-lg-12">
    <h2>Article made in {{ $city->city_name }}</h2>
    <hr>
    @foreach ($city->article as $article)
      <div class="well">
      <!-- $article->user->name adalah kolom name dari table user -->
      <h3>{{ $article->title }} By <a href="{{ url('user/'.$article->user_id.'')}}">{{ $article->user->name }}</a></h3>
      <strong>Tag:</strong>
      <ul> 
      @foreach($article->tags as $tag)
        <li>{{ $tag->tag_name }}</li>
      @endforeach
      </ul>
      <p>{{ $article->content }}</p>
      <hr>
      <h4>Comments</h4>
      @foreach($article->comments as $comment)
        <p>{{ $comment->content }}</p>
      @endforeach
      </div> 
    @endforeach
  </div>
</div>

Nah, output dari script diatas adalah seperti berikut:

Output Has Many Through

OK, sekarang kita lanjut ke relasi table pada laravel dengan eloquent yang berikutnya yaitu Polymorphic Relation.

Relasi Table Pada Laravel Dengan Eloquent – Polymorphic Relation

Polymorphic Relation memungkinkan kamu untuk merelasikan 1 entitas dengan banyak entitas. Contohnya seperti ini, setiap user dan artikel dapat memiliki komentar. Nah, daripada membuat 2 buah table komentar, kita dapat membuat 1 table saja untuk menampung komentar tersebut dan menampilkannya berdasarkan tipe Model.

DROP TABLE IF EXISTS `comments`;
CREATE TABLE `comments` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `content` text NOT NULL,
  `user_id` int(11) NOT NULL,
  `commentable_id` int(11) NOT NULL,
  `commentable_type` varchar(50) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`),
  CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `comments` (`id`, `content`, `user_id`, `commentable_id`, `commentable_type`, `created_at`, `updated_at`) VALUES
(1, 'This user is awesome', 2,  1,  'User', '2015-08-31 15:03:57',  '0000-00-00 00:00:00'),
(2, 'This article is awesome!', 2,  1,  'Article',  '2015-08-31 15:04:47',  '0000-00-00 00:00:00');

Dapat dilihat bahwa disitu ada kolom bernama commentable_id dan commentable_type. Kolom commentable_id berfungsi sebagai parameter id, baik id dari table articles maupun table users, sedangkan commentable_type berfungsi untuk mengidentifikasi apakah comment ini untuk model User atau model Article. Langsung saja kita buat model untuk table comments ini.

<?php

class Comment extends Eloquent {
	protected $table = 'comments';

	public function commentable() {
		return $this->morphTo();
	}
}

Lalu kita tambahkan method berikut pada model User.php dan juga Article.php

public function comments() {
    return $this->morphMany('Comment','commentable');
}

Setelah itu kita modifikasi views pada article, user dan juga city.

<div class="row">
  <div class="col-lg-12">
  		<h2>Article</h2>
  		<hr>
  		@if ($count > 0)
  			@foreach ($articles as $article)
  				<div class="well">
          <!-- $article->user->name adalah kolom name dari table user -->
  				<h3>{{ $article->title }} By <a href="{{ url('user/'.$article->user_id.'')}}">{{ $article->user->name }}</a></h3>
          <strong>Tag:</strong>
          <ul> 
          @foreach($article->tags as $tag)
            <li>{{ $tag->tag_name }}</li>
          @endforeach
          </ul>
  				<p>{{ $article->content }}</p>
          <hr>
          <h4>Comments</h4>
          @foreach($article->comments as $comment)
            <p>{{ $comment->content }}</p>
          @endforeach
  				</div> 
  			@endforeach
		@else
	    <br><br>
	    <div class="alert alert-danger"><center>NO ARTICLE FOUND</center></div>
	    @endif
  </div>
</div>
<div class="row">
  <div class="col-lg-12">
  		<h2>Profile : {{ $user->name }}</h2>
  		<strong>Address:</strong> {{ $user->address->address }}
  		<br>
      <strong>City:</strong> {{ $user->city->city_name }}
      <br>
  		<strong>Role:</strong>
  		<ul>
	  		@foreach($user->roles as $role)
	  			<li>{{ $role->role_name }}</li>
	  		@endforeach
  		</ul>
      <strong>Tag:</strong>
      <ul> 
          @foreach($user->tags as $tag)
            <li>{{ $tag->tag_name }}</li>
          @endforeach
      </ul>
      <hr>
      <h2>Comments</h2>
      @foreach($user->comments as $comment)
        <div class="well">
          <p>{{ $comment->content }}</p>
        </div>
      @endforeach
     	<hr>
  		<h2>Articles</h2>
  		@foreach($user->articles as $article)
  			<div class="well">
  				<h4>{{ $article->title }}</h4>
  				<p>{{ $article->content }}</p>
  			</div>
  		@endforeach
  </div>
</div>
<div class="row">
  <div class="col-lg-12">
  		<h2>Article made in {{ $city->city_name }}</h2>
  		<hr>
			@foreach ($city->article as $article)
				<div class="well">
        <!-- $article->user->name adalah kolom name dari table user -->
				<h3>{{ $article->title }} By <a href="{{ url('user/'.$article->user_id.'')}}">{{ $article->user->name }}</a></h3>
        <strong>Tag:</strong>
        <ul> 
        @foreach($article->tags as $tag)
          <li>{{ $tag->tag_name }}</li>
        @endforeach
        </ul>
				<p>{{ $article->content }}</p>
        <hr>
        <h4>Comments</h4>
        @foreach($article->comments as $comment)
          <p>{{ $comment->content }}</p>
        @endforeach
				</div> 
			@endforeach
  </div>
</div>

Hasil akhir dari script diatas adalah sebagai berikut:

Output Polymorphic Relations User
Output Polymorphic Relations City
Output Polymorphic Relations Article

OK, sekarang kita lanjut ke relasi table di Laravel dengan Eloquent yang terakhir yaitu Many To Many Polymorphic Relations.

Relasi Table Pada Laravel Dengan Eloquent # Many To Many Polymorphic Relations

Hampir sama dengan Polymorphic Relations, Many To Many Polymorphic Relations mendukung lebih dari 1 table. Contohnya seperti ini, dalam sebuah artikel terdapat tag. Untuk memunculkan tag tersebut, kita membutuhkan 2 table yaitu adalah table tags dan table taggables.

Fungsi dari table tags adalah untuk menyimpan data master tag, sedangkan table taggable berfungsi untuk merelasikan table tags dengan table articles dan juga table users.

DROP TABLE IF EXISTS `tags`;
CREATE TABLE `tags` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `tag_name` varchar(50) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `tags` (`id`, `tag_name`, `created_at`, `updated_at`) VALUES
(1, 'Writer',   '2015-08-31 15:38:26',  '0000-00-00 00:00:00'),
(2, 'Article',  '2015-08-31 15:31:39',  '0000-00-00 00:00:00'),
(3, 'Tutorial', '2015-08-31 15:31:43',  '0000-00-00 00:00:00'),
(4, 'Blogger',  '2015-08-31 15:38:34',  '0000-00-00 00:00:00');
DROP TABLE IF EXISTS `taggables`;
CREATE TABLE `taggables` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `tag_id` int(11) NOT NULL,
  `taggable_id` int(11) NOT NULL,
  `taggable_type` varchar(50) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  KEY `tag_id` (`tag_id`),
  CONSTRAINT `taggables_ibfk_1` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `taggables` (`id`, `tag_id`, `taggable_id`, `taggable_type`, `created_at`, `updated_at`) VALUES
(1, 1,  1,  'User', '2015-08-31 15:32:39',  '0000-00-00 00:00:00'),
(2, 2,  1,  'Article',  '2015-08-31 15:32:57',  '0000-00-00 00:00:00'),
(3, 3,  1,  'Article',  '2015-08-31 15:33:25',  '0000-00-00 00:00:00'),
(4, 4,  1,  'User', '2015-08-31 15:39:15',  '0000-00-00 00:00:00');

Sekarang kita buat modelnya, buat model bernama Tag.php

<?php

class Tag extends Eloquent {
	protected $table = 'tags';

	public function article() {
        return $this->morphedByMany('Article', 'taggable');
    }

    public function user() {
        return $this->morphedByMany('User', 'taggable');
    }
}

Setelah itu kita tinggal menambahkan method berikut pada model User.php dan juga Article.php.

public function tags() {
    return $this->morphToMany('Tag', 'taggable');
}

Langkah terakhir adalah memodifikasi file views dari user dan article untuk menampilkan tag tersebut.

<div class="row">
  <div class="col-lg-12">
  		<h2>Article</h2>
  		<hr>
  		@if ($count > 0)
  			@foreach ($articles as $article)
  				<div class="well">
          <!-- $article->user->name adalah kolom name dari table user -->
  				<h3>{{ $article->title }} By <a href="{{ url('user/'.$article->user_id.'')}}">{{ $article->user->name }}</a></h3>
          <strong>Tag:</strong>
          <ul> 
          @foreach($article->tags as $tag)
            <li>{{ $tag->tag_name }}</li>
          @endforeach
          </ul>
  				<p>{{ $article->content }}</p>
          <hr>
          <h4>Comments</h4>
          @foreach($article->comments as $comment)
            <p>{{ $comment->content }}</p>
          @endforeach
  				</div> 
  			@endforeach
		@else
	    <br><br>
	    <div class="alert alert-danger"><center>NO ARTICLE FOUND</center></div>
	    @endif
  </div>
</div>
<div class="row">
  <div class="col-lg-12">
  		<h2>Profile : {{ $user->name }}</h2>
  		<strong>Address:</strong> {{ $user->address->address }}
  		<br>
      <strong>City:</strong> {{ $user->city->city_name }}
      <br>
  		<strong>Role:</strong>
  		<ul>
	  		@foreach($user->roles as $role)
	  			<li>{{ $role->role_name }}</li>
	  		@endforeach
  		</ul>
      <strong>Tag:</strong>
      <ul> 
          @foreach($user->tags as $tag)
            <li>{{ $tag->tag_name }}</li>
          @endforeach
      </ul>
      <hr>
      <h2>Comments</h2>
      @foreach($user->comments as $comment)
        <div class="well">
          <p>{{ $comment->content }}</p>
        </div>
      @endforeach
     	<hr>
  		<h2>Articles</h2>
  		@foreach($user->articles as $article)
  			<div class="well">
  				<h4>{{ $article->title }}</h4>
  				<p>{{ $article->content }}</p>
  			</div>
  		@endforeach
  </div>
</div>

Hasil output dari script diatas adalah sebagai berikut:

Output Many To Many Polymorphic Article
Output Many To Many Polymorphic User

Nah, sekian penjelasan saya tentang bagaimana cara melakukan join / relasi table di Laravel dengan Eloquent. Kamu bisa membaca lebih lanjut dokumentasi tentang Relationships di Laravel dan untuk mendownload full source dari tutorial ini, kamu bisa mengklik pada link di bawah ini. Silahkan tinggalkan komentar dan semoga bermanfaat. 😀

Download Link

Be First to Comment

    Tinggalkan Balasan

    Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *