Memiliki banyak tabel tidak lepas dari kebutuan dalam membangun sistem untuk aplikasi kita. Mungkin kita punya cara tersendiri tentang bagaimana mengelola data pada database dan membentuk struktur yang menunjang fleksibilitas dan kebutuhan mananjemen data.
Ketika suatu tabel membutuhkan informasi dan atau memiliki keterkaitan dengan tabel lain, yang perlu kita lakukan adalah menghubungkannya dengan membangun relasi; dan antar tabel saling mengikat dan dapat dipanggil kapanpun ketika dibutuhan.
Kemudian ketika suatu tabel terhubung dan atau antar tabel saling berhubungan, langkah selanjutnya yang perlu dipikirkan adalah bagaimana kita membuat permintaan malakukan kueri dan memproses data tabel tersebut.
Laravel Eloquent: Relasi Tabel Database
Laravel memiliki fitur atau cara yang dapat kita gunakan untuk melakukan kueri tabel database dengan pilihan metode sesuai relasi yang kita bangun.
Penggunaanya pun juga sangat mudah, dengan adanya eloquent di laravel kita hanya akan menghubungkan antar model yang ada.
Seperti apa, kita akan pelajari disini. Kita akan membuat relasi tabel database dan melakukan kueri di laravel.
Persiapan
Sebelum ke pembahasan dan penggunaan relasi, ada beberapa hal yang perlu kita buat terlebih dahulu, seperti menyiapkan project, route, controller, model, dan database untuk bahan contoh.
Instalasi Laravel dan Database
Mari kita mulai dari menginstall laravel dan membuat database lalu menghubungkannya.
laravel new laravel-relationships #atau composer create-project laravel/laravel laravel-relationships
Kita akan menggunakan MySQL database. Setelah project siap, silahkan buat database baru dan mengaturnya pada file .env
.
DB_DATABASE=laravel_relationships DB_USERNAME=root DB_PASSWORD=
Setelah selesai menyiapkan database dan menghubunkan dengan project, tahap selanjutnya kita buat file migrasi baru untuk membuat tabel.
Membuat Tabel, Kolom, dan Model
Kita gunakan perintah untuk membuat Model dan file migrasi sekaligus.
php artisan make:model Post -m
Kemudian kita buka file migrasi baru yang telah dibuat untuk kita tambahkan kolom. Silahkan buka dan buat seperti di bawah ini.
//...create_posts_table.php public function up() { Schema::create('posts', function (Blueprint $table) { $table->id(); $table->foreignId('user_id'); $table->string('title'); $table->text('body'); $table->timestamps(); }); }
Pada tabel posts kita tambahkan kolom user_id
yang merupakan kunci asing / foreign key yang akan menyimpan nilai primary key / kunci utama tabel induk.
Setelah dibuat kemudian kita jalankan perintah migrasi php artisan migrate
.
MariaDB [laravel_relationships]> show tables; +---------------------------------+ | Tables_in_laravel_relationships | +---------------------------------+ | failed_jobs | | migrations | | password_resets | | posts | | users | +---------------------------------+ 5 rows in set (0.080 sec)
Sampai disini, tabel, kolom dan model telah selesai kita buat.
Database Seeder
Kita akan gunakan seeder untuk mengisi tabel users
dan posts
; cara cepat dan mudah untuk menambahkan data yang akan kita gunakan sebagai data contoh.
Silahkan jalankan perintah di bawah ini. Kita buat dua file seeder.
php artisan make:seed UsersTableSeeder php artisan make:seed PostsTableSeeder
File seeder baru akan berada pada direktori database/seeders. Silahkan buka kedua file tersebut lalu buat seperti dibawah ini, sesuai file.
//UsersTableSeeder.php <?php namespace Database\Seeders; use Illuminate\Database\Seeder; class UsersTableSeeder extends Seeder { public function run() { $users = [ [ 'name' => 'user1', 'email' => '[email protected]', 'password' => bcrypt('12345678'), 'created_at' => new \DateTime, 'updated_at' => null, ], [ 'name' => 'user2', 'email' => '[email protected]', 'password' => bcrypt('12345678'), 'created_at' => new \DateTime, 'updated_at' => null, ], ]; \DB::table('users')->insert($users); } }
//PostsTableSeeder.php <?php namespace Database\Seeders; use Illuminate\Database\Seeder; class PostsTableSeeder extends Seeder { public function run() { $posts = [ [ 'user_id' => 1, 'title' => "Lorem Ipsum", 'body' => 'Lorem ipsum is placeholder text commonly used in the graphic, print, and publishing industries for previewing layouts and visual mockups.', 'created_at' => new \DateTime, 'updated_at' => null, ], [ 'user_id' => 1, 'title' => "What is Lorem Ipsum?", 'body' => 'From its medieval origins to the digital era, learn everything there is to know about the ubiquitous lorem ipsum passage.', 'created_at' => new \DateTime, 'updated_at' => null, ], [ 'user_id' => 2, 'title' => "Origins and Discovery", 'body' => 'Lorem ipsum began as scrambled, nonsensical Latin derived from Cicero"s 1st-century BC text De Finibus Bonorum et Malorum.', 'created_at' => new \DateTime, 'updated_at' => null, ], ]; \DB::table('posts')->insert($posts); } }
Kemudian buka file DatabaseSeeder.php lalu tambahkan class kedua seeder di dalam run()
method.
public function run() { $this->call([ UsersTableSeeder::class, PostsTableSeeder::class, ); }
Terakhir jalankan perintah seeding.
php artisan migrate --seed
Setelah selesai silahkan lihat database untuk melihat data yang dibuat.
Kita telah selesai menyiapkan bahan, atau project dengan database dan memiliki data untuk kita gunkanan. Selanjutnya kita akan mulai mempelajari relasi di laravel dan melakukan kueri.
One To One
Pembahasan relasi laravel kita mulai dari One To One atau satu ke satu. One To One digunakan untuk kueri relasi yang hanya memiliki satu kepunyaan.
Relasi One To One menggunkan method hasOne()
yang ditambahkan pada model terkait dan menggunakan nama class model sebagai argumen.
Untuk lebih jelas dan mudah dipahami mari kita membuatnya. Sebagai contoh kita akan menampilkan data user dan membuat relasi untuk menampilkan data post yang dimiliki user.
Pada Model User.php silahkan tambahkan dibawah ini.
public function post() { return $this->hasOne(Post::class); }
Lalu pada route web.php buat seperti di bawah ini.
use App\Models\User; Route::get('/users/{user}', function ($id) { $user = User::with('post')->find($id); return response()->json($user, 200); });
Kemudian kita buka browser dengan url http://localhost:8000/users/1
. Hasilnya seperti gambar dibawah ini.
Meskipun banyak data pada tabel posts yang dimiliki user, metode hasOne hanya menampilkan satu data terkait.
Silahkan install JSON Formatter extention untuk membuat tampilan json lebih mudah dibaca.
One To Many
Selanjutnya ada One To Many. One To Many digunakan untuk relasi antara satu model yang memiliki hubungan dengan satu atau banyak model. Contohnya seperti satu user memiliki banyak post.
Menggunakan hasMany()
method yang ditambahkan pada model terkait.
Kita buka model User.php dan tambahkan dibawah ini.
public function posts() { return $this->hasMany(Post::class); }
Kemudian pada route web.php buat seperti dibawah ini.
Route::get('/users/{user}', function ($id) { $user = User::with('posts')->find($id); return response()->json($user, 200); });
Kita lihat kembali pada browser dengan alamat yang sama. Hasilnya seperti pada gambar di bawah ini.
One To Many (Inverse) / Belongs To
Selanjutnya ada One To Many (Inverse) menggunakan method belongsTo()
yang merupakan kebalikan dari hasMany()
, dimana hubungan dibuat pada model anak yang dapat memanggil orang tua / tabel induk.
Contohnya seperti pada kasus kita, dimana tabel posts memilki user_id
dan terhubung dengan tabel users
yang merupakan parent / orang tua.
Jadi kita bisa menampilkan atau mengambil data user dari postingan, atau menampilkan postingan dengan yang memiliki postingan tersebut.
Mari kita mencobanya. Kita buka model Post.php dan tambahkan di bawah ini.
public function user() { return $this->belongsTo(User::class); }
Lalu pada route web.php tambahkan dibawah ini.
use App\Models\Post; Route::get('/posts/{id}', function ($id) { $post = Post::with('user')->find($id); return response()->json($post, 200); });
Kita lihat pada browser dengan alamat http://localhost:8000/posts/1
. Angka 1 merupakan key / ID dari post; hasilnya seperti gambar dibawah ini.
Many To Many
Selanjutnya ada Many To Many atu banyak ke banyak. Many To Many digunakan untuk hubungan ke banyak tabel, seperti satu tabel memilki banyak tabel atau menghubungkan banyak tabel sebagai perantara.
Mari kita buat contoh untuk lebih jelasnya.
Sebagai contoh kita akan membuat sistem 'roles' atau peran suatu user dengan tiga tabel yang akan ber-relasi.
Mari kita tambahkan tabel baru pada database terlebih dahulu. Silahkan jalankan perintah di bawah ini.
php artisan make:model Role -m php artisan make:migration create_role_user_table
Buka kedua file migrasi tersebut dan buat seperti dibawah ini.
//...create_roles_table.php public function up() { Schema::create('roles', function (Blueprint $table) { $table->id(); $table->string('name'); $table->timestamps(); }); }
//...create_role_user.php public function up() { Schema::create('role_user', function (Blueprint $table) { $table->id(); $table->foreignId('user_id'); $table->foreignId('role_id'); $table->timestamps(); }); }
Kemudian kembali kita buat file seeder untuk mengisi kedua tabel baru tersebut.
php artisan make:seed RolesTableSeeder php artisan make:seed Role_UserTableSeeder
Lalu buat seperti di bawah ini.
//RolesTableSeeder.php public function run() { $roles = [ [ 'name' => 'user', 'created_at' => new \DateTime, 'updated_at' => null, ], [ 'name' => 'admin', 'created_at' => new \DateTime, 'updated_at' => null, ], ]; \DB::table('roles')->insert($roles); }
//Role_UserTableSeeder.php public function run() { $roles = [ [ 'user_id' => 1, 'role_id' => 1, 'created_at' => new \DateTime, 'updated_at' => null, ], [ 'user_id' => 2, 'role_id' => 2, 'created_at' => new \DateTime, updated_at' => null, ], [ 'user_id' => 1, 'role_id' => 2, 'created_at' => new \DateTime, 'updated_at' => null, ], ]; \DB::table('role_user')->insert($roles); }
Pada DatabaseSeeder.php buat seperti di bawah ini.
//DatabaseSeeder.php public function run() { $this->call([ // UsersTableSeeder::class, // PostsTableSeeder::class, RolesTableSeeder::class, Role_UserTableSeeder::class, ]); }
Terakhir lakukan migrasi php artisan migrate --seed
MariaDB [laravel_relationships]> show tables; +---------------------------------+ | Tables_in_laravel_relationships | +---------------------------------+ | failed_jobs | | migrations | | password_resets | | posts | | role_user | | roles | | users | +---------------------------------+
Kita tambahan dua tabel roles
dan user_role
. user_role
kita digunakan sebagai perantara antara tabel users dan tabel roles yang akan menyimpan kedua primary key, dan tidak membutuhkan model.
Sekarang buka user.php dan tambahkan dibawah ini.
public function roles() { return $this->belongsToMany(Role::class); }
Pada route web.php tambahkan dibawah ini.
Route::get('/users/{user}', function ($id) { $user = User::with('posts','roles')->find($id); return response()->json($user, 200); });
Kita lihat pada browser dengan alamat http://localhost:8000/users/1
. Hasilnya seperti gambar dibawah.
Satu user dapat memilki lebih dari satu role / peran.
Kita juga bisa menampilkan user dengan roles pada permintaan post. Pada route posts buat seperti dibawah ini.
Route::get('/posts/{id}', function ($id) { $post = Post::with('user.roles')->find($id); return response()->json($post, 200); });
Jika kita lihat pasa object roles terdapat atribut pivot, dimana fungsinya untuk mengakses tabel perantara atau tabel role_user
.
Otomatis atribut pivot ini akan ada dan secara default menampilkan ID / keys tabel yang ada pada tabel perantara.
Namun kita juga bisa menambahkan atribut lain yang ingin kita tampilkan. Sebagai contoh silahkan tambahkan dibawah ini pada model User.php.
public function roles() { return $this->belongsToMany(Role::class)->withPivot('created_at'); }
Untuk diperhatikan bahwa kolom yang ingin ditampilkan pada pivot harus tersedia pada tabel tersebut.
Silahkan lihat pada browser dengan alamat http://localhost:8000/users/1
.
Penambahkan kolom created_at
diatas hanya contoh untuk ditambahkan secara manual. Kita bisa manampilkan keterangan waktu secara otomatis menggunakan withTimestamps()
public function roles() { return $this->belongsToMany(Role::class)->withTimestamps(); }
Silahkan dicoba dan lihat hasilnya. Kita sampai disini.
Selesai
Cukup panjang yang kita buat dan kita pelajari. Kita telah selesai membuat dan mempelajari penggunaan relasi di laravel.
Kita sampai disini dulu. Silahkan dicoba, dikembangkan dan lakukan eksperimen.