Memahami Laravel Route Model Binding: Langkah Demi Langkah
Dulunya, mungkin ini sangat repot, kita harus definisikan key apa yang ingin kita jadikan wildcardnya seperti berikut.
Perkenalan
Route model binding dalam Laravel adalah fitur yang memudahkan Anda dalam mengambil record database berdasarkan parameter yang ada di URL. Laravel akan secara otomatis mencocokkan parameter URL dengan instance model yang sesuai.
Sebelumnya
Sebelum adanya model binding, Anda mungkin akan menuliskan kode seperti ini:
Route::get('users/{id}', function ($id) {
return User::findOrFail($id);
});
Atau mungkin jika dengan field lainnya:
Route::get('users/{username}', function ($username) {
return User::where('username', $username)->firstOrFail();
});
Menggunakan Route Model Binding
Ketika kita menggunakan route model binding ini, kita tidak perlu lagi membuat semacam query di dalam controller nya. Yang perlu kita lakukan adalah menuliskan versi singular dari model yang ingin kita gunakan di dalam route. Contohnya seperti ini:
Route::get('users/{user}', function (App\Models\User $user) {
return $user->email;
});
By default jika kita tidak memberikan key pada wildcard, maka Laravel akan mencocokkan dengan primary key dari model yang kita gunakan. Jadi dalam case ini Laravel akan mencocokkan dengan field id dari model User.
Customizing Key Name
Namun, jika kita ingin mencocokkan dengan field lainnya, kita bisa menambahkan key pada wildcard nya. Contohnya seperti ini:
Route::get('users/{user:username}', function (App\Models\User $user) {
return $user->email;
});
Dengan begitu, kita akan mengunjugi URL seperti ini:
http://localhost:8000/users/john
Pastinya kita akan mendapatkan email dari user dengan username john.
2 Identifier
Terkadang ada kalanya kita ingin menampilkan object bukan hanya dari 1 key, bisa jadi 2 bahkan 3. Misal, di dalam model User kita memiliki field username dan id. Kita ingin mencocokkan kedua field tersebut. Caranya adalah dengan menambahkan key nya seperti ini:
Route::get('users/{user:id,username}', function (App\Models\User $user) {
return $user->email;
});
Itu harapannya ya guys. Tapi sebenarnya itu belum bisa hahaha. Yang bisa kita lakukan saat ini adalah seperti:
Route::get('users/{identifier}', function ($identifier) {
return User::where('username', $identifier)->orWhere('id', $identifier)->firstOrFail();
});
Bind Route
Namun jika seperti itu, kita akan di tuntut untuk menuliskan query nya di dalam controller. Jadi, bagaimana cara kita untuk mencocokkan 2 identifier tersebut? Kita bisa menggunakan Route::bind pada RouteServiceProvider seperti ini:
use App\Models\User;
Route::bind('user', function ($value) {
return User::where('username', $value)->orWhere('id', $value)->firstOrFail();
});
Dengan begitu, kita bisa menggunakan simpel route seperti ini:
Route::get('users/{user}', function (App\Models\User $user) {
return $user->email;
});
Lebih dari 1 wildcard
Explicit Binding
Ketika Anda sudah paham tentang route model binding, Anda mungkin akan bertanya-tanya, bagaimana jika kita ingin menggunakan 2 model dalam 1 route? Misal kita ingin menampilkan artikel dari kategori tertentu. Kita bisa menggunakan route model binding seperti ini:
Route::get('articles/{category:slug}/{article:slug}', [ArticleController::class, 'show']);
Dalam case ini kita akan menggunakan controller. Jika kita membuat wildcard nya 2, pastinya di dalam method nya akan menerima 2 model.
use App\Models\Article;
use App\Models\Category;
public function show(Category $category, Article $article)
{
return $article;
}
Dan ini akan otomatis Not found (404) jika memang kategori yang diberikan tidak seusai dengan yang berelasi dengan artikel.
Implicit Binding
Namun, jika kita coba untuk tidak menggunakan explicit binding, maka Not found tidak akan terjadi. Contoh nya seperti ini:
Route::get('articles/{category}/{article}', [ArticleController::class, 'show']);
Jika kita coba untuk mengunjungi URL seperti ini:
http://routing.test/articles/2/1
Yang saat ini, pada tabel artikel tidak memiliki relasi ke kategori dengan id 2. Namun, kita tidak akan mendapatkan Not found. Karena Laravel akan mencoba untuk mencocokkan dengan primary key dari model yang kita gunakan. Jadi, jika kita ingin menggunakan implicit binding, kita harus menambahkan key nya seperti contoh pada explicit binding.
Scoped Binding
Pertanyaan nya adalah, bagaimana jika kita tidak ingin menggunakan key nya? Karena memang kita ingin dari keduanya di identifikasi dari id nya. Kita bisa menggunakan scoped binding seperti ini:
Route::get('articles/{category}/{article}', [ArticleController::class, 'show'])->scopeBindings();
Maka dengan begitu, ketika kita mengunjungi url yang sama seperti di atas, kita akan mendapatkan Not found.
Shallow Binding
Ketika kita bekerja dengan route resource. Dalam case ini, kita akan beranggapan bahwa ada table playlist dan juga episode. Yang mana 2 tabel tersebut akan benar-benar berhubungan dalam case apapun.
Maka route yang kita lakukan adalah seperti:
Route::resource('{playlist}/{episode}', EpisodeController::class);
Dalam case ini, kita benar-benar ingin bahwa yang ada di url adalah model yang berelasi. Dengan resource kita tidak bisa menggunakan yang namanya scopeBindings(), maka kita bisa menggunakan ->shallow()() seperti ini:
Route::resource('{playlist}/{episode}', EpisodeController::class)->shallow();
Dengan begitu, jika playlist atau episode tidak berelasi satu sama lain, maka kita akan mendapatkan Not found.
Trash
Ketika Anda menggunakan fitur soft deletes di laravel, semua route yang telah dihapus akan otomatis mendapatkan Not found. Namun, jika Anda ingin menampilkan route yang telah dihapus, Anda bisa menggunakan withTrashed() seperti ini:
Route::get('articles/{article}', [ArticleController::class, 'restore'])->withTrashed();
Route Caching
Ketika Anda menggunakan route caching, maka semua route yang Anda buat akan di cache. Sehingga, ketika Anda membuat route baru, maka route tersebut tidak akan terbaca. Untuk mengatasi hal tersebut, Anda bisa menggunakan php artisan route:clear untuk menghapus cache route Anda.
Semoga artikel ini bermanfaat untuk Anda. Jika ada pertanyaan, silahkan bertanya di discord atau langsung dm saya di twitter. Terima kasih.
Irsyad A. Panjaitan
Let's start living like no one can help us in any event, so that when we are helped in certain times, it becomes a plus in itself.
Artikel yang Terkait
- Belajar Cache Flexible di Laravel
Irsyad A. Panjaitan
- Membuat Fitur Multi Bahasa di Laravel Inertia React
Irsyad A. Panjaitan
- Laravel Script: composer run dev
Irsyad A. Panjaitan
- Apa yang Baru di Inertia.js 2.0
Irsyad A. Panjaitan
- Membuat Custom Rule Validator untuk Nomor Telepon Indonesia dengan Laravel
Abd. Asis
- Like System dengan Laravel Polymorphic
Irsyad A. Panjaitan
- Laravel Dengan Multi Koneksi Database: Panduan Langkah demi Langkah
Abd. Asis