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.
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.
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
- URL: http://localhost:8000/api/post/1
- URL: http://localhost:8000/api/post/2
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')); });
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