Laravel Many To Many (Polymorphic): Membuat Sistem Tag

whynwd

whynwd Senin, 21 Juni 2021

Laravel Many To Many (Polymorphic): Membuat Sistem Tag

Ada beberapa jenis relasi di laravel yang bisa kita gunakan untuk menghubungkan antar tabel, tergantung seperti apa pola hubungkan yang kita buat. Misalnya untuk suatu postingan blog, dimana satu postingan dapat memiliki banyak tag / label atau satu label dapat dimiliki banyak postingan.

Biasanya kumpulan tag atau label memiliki tabel tersendiri di database, dan kita perlu membuat relasi untuk menggunakannya, dikaitkan dengan tabel lain.

Untuk contoh ini, kita bisa gunakan relasi polimorfik banyak ke banyak / Many To Many (Polymorphic). Kita dapat menghubungkan satu model dengan banyak model lainnya.

Bagaimana penerapan atau cara penggunaanya, mari kita buat metode insert sederhana di laravel.

Struktur Tabel

Silahkan install laravel, buat database dan hubungkan dengan aplikasi.

laravel new laraveltags
//.env
DB_DATABASE=db_laraveltags
DB_USERNAME=root
DB_PASSWORD=

Kita akan tambahkan beberapa tabel di database. Selain tabel untuk postingan dan daftar tag, kita membutuhkan sebuah tabel lain yang digunakan sebagai tabel perantara untuk menyimpan identitas tag dan tabel lain yang dikaitkan.

Mari kita buat 3 file migrasi. 2 tabel dengan model, dan 1 tabel tanpa model.

php artisan make:model Post -m

php artisan make:model Tag -m

php artisan make:migration create_taggables_table

Kemudian tambahkan kolom seperti di bawah ini, sesuai file migrasi.

//...create_posts_table.php
public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title'); 
        $table->text('body');
        $table->timestamps();
    });
}
//...create_tags_table.php
public function up()
{
    Schema::create('tags', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->timestamps();
    });
}
//...create_taggables_table.php
public function up()
{
    Schema::create('taggables', function (Blueprint $table) {
        $table->id();
        $table->integer('tag_id');
        $table->integer('taggable_id');
        $table->string('taggable_type');
        $table->timestamps();
    });
}

Kemudian lakukan migrasi.

php artisan migrate
//mysql command line
MariaDB [db_laraveltags]> show tables;
+--------------------------+
| Tables_in_db_laraveltags |
+--------------------------+
| failed_jobs              |
| migrations               |
| password_resets          |
| posts                    |
| taggables                |
| tags                     |
| users                    |
+--------------------------+
7 rows in set (0.003 sec)

Relasi Model

Selanjutnya kita hubungkan model yang akan dikaitkan. Saat kita mengambail data terkait pada model lain, kita relasikan pada model yang dilakukan kueri.

Untuk kueri model 'post' yang dikaitkan dengan tag, buat relasi menggunakan metode morphToMany pada model Post.php seperti di bawah ini.

//Post.php
public function tags()
{
    return $this->morphToMany(Tag::class, 'taggable');
}

taggable merupakan nama dari relasi sebagai identitas untuk nama kolom yang menerima value.

Untuk kueri model 'tag' yang dikaitkan dengan model lain atau model induk, kita gunakan metode morphedByMany seperti di bawah ini.

//Tag.php
public function posts()
{
    return $this->morphedByMany(Post::class, 'taggable');
}

Menyimpan Data dengan Relasi

Selanjutnya kita buat metode insert record, menyimpan ke database dengan relasi model terkait. Kita akan meyimpan record ke tabel posts dan mengambil tag dari tabel tags.

Namun sebelum itu, kita tambahkan beberapa tag terlebih dahulu ke tabel tags menggunakan seeder.

php artisan make:seeder TagsTableSeeder

Buka database > seeders > TagsTableSeeder.php, pada metode run() buat seperti di bawah ini.

public function run()
{
    $tags = [
        [
            'name' => "Laravel", 
            'created_at' => new \DateTime,
            'updated_at' => null,
        ], 
        [
            'name' => "PHP", 
            'created_at' => new \DateTime,
            'updated_at' => null,
        ], 
        [
            'name' => "HTML", 
            'created_at' => new \DateTime,
            'updated_at' => null,
        ],
        [
            'name' => "CSS", 
            'created_at' => new \DateTime,
            'updated_at' => null,
        ], 
        [
            'name' => "JavaScript", 
            'created_at' => new \DateTime,
            'updated_at' => null,
        ]
    ];

    \DB::table('tags')->insert($tags);
}

Buka database > seeders > TagsTableSeeder.php, tambahkan class seeder di dalam metode run().

public function run()
{ 
    $this->call([ TagsTableSeeder::class ]);
}

Terakhir, jalankan seeder.

php artisan db:seed
MariaDB [db_laraveltags]> select id, name from tags;
+----+------------+
| id | name       |
+----+------------+
|  1 | Laravel    |
|  2 | PHP        |
|  3 | HTML       |
|  4 | CSS        |
|  5 | JavaScript |
+----+------------+
5 rows in set (0.000 sec)

Kita sudah memiliki beberapa tag dan siap digunakan. Sekarang kita membuat metode insert record baru.

Mari kita buat sebuah controller. Kita buat dengan nama PostController.

php artisan make:controller PostController

Buka PostController.php, buat seperti di bawah ini.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Models\Post; 

class PostController extends Controller
{
   public function store(Request $request)
   {
      $post = new Post; 
      $post->title = $request->title;   
      $post->body = $request->body; 

      $post->save();
      
      $post->tags()->sync($request->taggable);

      return response()->json($post, 201);
   }
}

Kita gunakan asosiasi sync yang akan menyimpan ID dari model terkait dan ID dari tag yang kita input ke tabel perantara.

Selanjutnya kita buat route. Buka routes > api.php, tambahkan route di bawah ini.

use App\Http\Controllers\PostController;

Route::post('post/create',[PostController::class, 'store']);

Sampai disini mari kita mencobanya di postman. Silahkan buka aplikasi postman dan buat request seperti gambar di bawah.

php artisan serve
  • URL: http://localhost:8000/api/post/create
  • Method: POST

Gunakan taggable pada key dan ID dari tag sebagi value.

Laravel Many To Many (Polymorphic): Membuat Sistem Tag

Jika dilihat pada tabel perantara taggables di database seperti di bawah ini.

MariaDB [db_laraveltags]> select * from taggables;
+----+--------+-------------+-----------------+------------+------------+
| id | tag_id | taggable_id | taggable_type   | created_at | updated_at |
+----+--------+-------------+-----------------+------------+------------+
|  1 |      1 |           1 | App\Models\Post | NULL       | NULL       |
+----+--------+-------------+-----------------+------------+------------+
1 row in set (0.001 sec)

Karena 'post' dapat memiliki lebih dari satu tag, metode sync juga mendukung array. Silahkan coba buat request dengan beberapa ID tag seperti gambar di bawah ini.

Laravel Many To Many (Polymorphic): Membuat Sistem Tag
MariaDB [db_laraveltags]> select * from taggables;
+----+--------+-------------+-----------------+------------+------------+
| id | tag_id | taggable_id | taggable_type   | created_at | updated_at |
+----+--------+-------------+-----------------+------------+------------+
|  1 |      1 |           1 | App\Models\Post | NULL       | NULL       |
|  2 |      2 |           2 | App\Models\Post | NULL       | NULL       |
|  3 |      3 |           2 | App\Models\Post | NULL       | NULL       |
|  4 |      4 |           2 | App\Models\Post | NULL       | NULL       |
+----+--------+-------------+-----------------+------------+------------+
4 rows in set (0.000 sec)

Kueri dengan Relasi

Kita lanjutkan untuk melakukan kueri dengan relasi model terkait. Silahkan buat method pada PostController.php dan route di api.php seperti di bawah.

//PostController.php
public function index()
{
   $posts = Post::all();
   $tags = Tag::all();  
   
   return response()->json(compact('posts', 'tags'), 200);
}

public function show(Post $post) 
{
   $tags = $post->tags()->get();
   
   return response()->json(compact('post', 'tags'), 200);
}
//api.php
Route::get('posts',[PostController::class, 'index']); 

Route::get('post/{post}',[PostController::class, 'show']);

Selanjutnya tinggal mencobanya. Silahkan Buat request baru di postman.

  • URL: http://localhost:8000/api/posts
  • Method: GET
  • URL: http://localhost:8000/api/post/ID-POST
  • Method: GET

Atau bisa juga menggunakan browser.

  • URL: http://localhost:8000/api/posts
Laravel Many To Many (Polymorphic): Membuat Sistem Tag
  • URL: http://localhost:8000/api/post/1
Laravel Many To Many (Polymorphic): Membuat Sistem Tag
  • URL: http://localhost:8000/api/post/2
Laravel Many To Many (Polymorphic): Membuat Sistem Tag

HTML Request Form

Untuk penggunaan pada form input, kita gunakan nama properti yang sama seperti 'key' pada form-data di postman.

Kita memiliki 'title', 'body', dan 'taggable' yang merupakan nama dari relasi yang buat untuk di tetapkan pada atribuat tag html input.

//welcome.blade.php
<form method="POST" action="/api/post/create">
  @csrf 
  <input type="text" name="title" placeholder="title">
  <input type="text" name="body" placeholder="body"> 
  <select name="taggable" id="taggable">
    <option value="">--Pilih tag--</option>
    @foreach($tags as $tag)
    <option value="{{$tag->id}}">{{$tag->name}}</option>
    @endforeach
  </select>
  <button type="submit">Submit</button>
</form>
//web.php 
use App\Models\Tag;

Route::get('/', function () {
    $tags = Tag::all();
    return view('welcome', compact('tags')); 
});
Laravel Many To Many (Polymorphic): Membuat Sistem Tag

Selesai

Demikian contoh penggunaan relasi Many To Many laravel pada sistem tag atau label postingan. Silahkan dicoba, dikembangkan, dan lakukan eksperimen.

Postingan terkait relasi: Belajar Relasi Eloquent Laravel

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel