Aplikasi yang sudah dibangun sebelumnya itu semua proses nya masih ditangani komponen `routes` kita, contohnya ketika kita melakukan request ke halaman `/posts` untuk menampilkan semua data dari blog post kita dilakukan di dalam routes, begitu pula dengan proses menampilkan halaman views, itu juga dilakukan di dalam routes. Hal tersebut tidak tepat, karena jika kita ingin menerapkan konsep MVC (Model, View, Controller) maka 2 proses tersebut seharusnya kita pisahkan sesuai dengan komponen nya.
Aplikasi yang sudah dibangun sebelumnya itu semua proses nya masih ditangani komponen routes kita, contohnya ketika kita melakukan request ke halaman /posts untuk menampilkan semua data dari blog post kita dilakukan di dalam routes, begitu pula dengan proses menampilkan halaman views, itu juga dilakukan di dalam routes. Hal tersebut tidak tepat, karena jika kita ingin menerapkan konsep MVC (Model, View, Controller) maka 2 proses tersebut seharusnya kita pisahkan sesuai dengan komponen nya.
Misalkan jika kita ingin bekerja atau berhubungan dengan data, maka kita harus menyimpan kode nya di dalam komponen Model. Dan jika terdapat sebuah proses seperti memilih, menampilkan views, maka kita harus menyimpan kode nya di dalam komponen Controller.
Maka pada bagian ini, kita akan coba menerapkan konsep MVC dengan cara memisahkan kode nya ke dalam komponen-komponen yang terpisah. Sehingga nantinya kita akan belajar membuat model dan controller dan bagaimana cara menggabungkan ketiga komponen MVC tersebut.
Dan sedikit ada perubahan nama route pada aplikasi sebelumnya dari route /blog menjadi /posts di file routes/web.php
routes/web.php
Route::get('/blog', function () { ...});
Menjadi
routes/web.php
Route::get('/posts', function () { ...});
Kemudian navbar anchor link nya juga di file resources/views/partials/navbar.blade.php
Jika kalian sudah menginstall extension nya, kalian bisa membuat sebuah model dengan menggunakan command palette milik nya Visual Studio Code. Caranya kalian cukup tekan CTRL + P kemudian ketikan Artisan: Make Model
Sebelumnya kita menyimpan data blog post di lokasi routes nya, nah cara tersebut sebetulnya tidak tepat dan tidak efisien (karena kita menduplikat variable tersebut pada route single post nya). Untuk mengatasi hal tersebut, kita disini akan mencoba memindahkan data blog post tersebut kedalam sebuah model.
Kita akan memilih pembuatan model menggunakan cara PHP Artisan yang dimana akan menjalankan artisan melalui aplikasi Terminal. Maka disini kita jalankan dengan perintah seperti berikut ini
bash
php artisan make:model Post
Maka sekarang terdapat sebuah file baru di folder app/Models dengan nama file nya adalah Post.php. Pada model tersebut terdapat sebuah kode
php
use Illuminate\Database\Eloquent\Factories\HasFactory;use Illuminate\Database\Eloquent\Model;
yang dimana berfungsi untuk nantinya terhubung kedalam database, namun karena kita belum butuh maka bisa kita hapus dan extends pada Class Model nya juga bisa kita hapus
Sehingga sekarang isi dari file model Post.php tersebut seperti berikut ini
Selanjutnya kita coba cut atau ambil data $blog_posts dari route /posts agar disimpan di Model Post.php dengan access modifier private dan juga static
maka sekarang isi file Post.php seperti berikut ini
php
<?phpnamespace App\Models;class Post{ private static $blog_posts = [ [ 'title' => 'Judul Post Pertama', 'slug' => 'judul-post-pertama', 'author' => 'Arman Dwi Pangestu', 'body' => 'Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quasi aliquid perspiciatis possimus. Quae sapiente molestiae perferendis ut dolorum illum fugit corrupti! Ratione pariatur quis odio! Explicabo quo incidunt velit aliquam iure, doloribus natus molestiae ab officiis, ea distinctio fugit dolores eos quam magni aliquid libero nihil ex iusto unde? Voluptates!' ], [ 'title' => 'Judul Post Kedua', 'slug' => 'judul-post-kedua', 'author' => 'Sandhika Galih', 'body' => 'Lorem, ipsum dolor sit amet consectetur adipisicing elit. Delectus, nobis qui. Officia eius, debitis eveniet nisi culpa quas, voluptate enim impedit ipsa corrupti sapiente nesciunt mollitia facilis at cumque laudantium.' ] ];}
Dan isi dari route /posts nya menjadi seperti berikut ini
Catatan:
Jika kalian mendapatkan error pada Class Post nya, maka kalian harus melakukan import Class nya pada bagian paling atas file dengan perintah berikut ini:
php
use App\Models\Post;
Jika kalian ingin mempermudah masalah import namespace tersebut, kalian bisa install Extension VSCode yang namanaya PHP Namespace Resolver. Extension tersebut jika kita melakukan klik kanan pada VSCode maka kita bisa melakukan Import All Classes, sehingga jika ada Class yang error karena namespace nya tidak diload, dengan extension tersbeut akan otomatis terimport semua namespace nya.
Method all() juga disini belum kita buat, sehingga pasti akan muncul error
Setelah routes dan model nya terhubung, sekarang kita buat method all() nya di Class Post atau Model nya seperti berikut ini
Catatan: Tips Object Oriented Programming!
Dikarenakan disini property $blog_posts nya adalah static maka kita harus menggunakan keyword self::$property, namun jika property nya biasa maka kita menggunakan keyword $this->property.
php
<?phpnamespace App\Models;class Post{ private static $blog_posts = [ ... ]; public static function all() { return self::$blog_posts; }}
Nah, pemindahan data dari routes ke model sudah selesai, jika kalian melakukan refresh pada web browser dengan routes /posts maka tidak akan muncul error, namun jika kalian masuk ke dalam single post nya, data nya masih menggunakan data dari routes nya (bukan dari model).
Selanjutnya kita akan ubah juga agar data dari single post menggunakan data dari model nya. Sekarang ubah route single page atau route slug nya menjadi seperti berikut ini
php
// Halaman Single PostRoute::get('posts/{slug}', function ($slug) { return view('post', [ 'title' => 'Single Post', 'post' => Post::find($slug) ]);});
Selanjutnya kita buat sebuah method static lagi dengan nama method nya adalah find() di Model Post nya
php
<?phpnamespace App\Models;class Post{ private static $blog_posts = [ ... ]; public static function all() { return self::$blog_posts; } public static function find($slug) { $posts = self::$blog_posts; $post = []; foreach ($posts as $p) { if ($p['slug'] === $slug) { $post = $p; } } return $post; }}
Maka sekarang data dari view single post nya sudah mengambil dari Model yang sudah kita buat dan kode pada bagian routes nya juga sudah menjadi rapih (tidak ada data, karena data memang seharusnya di tempatkan pada komponen model).
Kita bisa ubah data yang kita ambil agar menjadi sesuatu yang disebut dengan collection di Laravel. Apa itu Collection? Collection sebetulny adalah pembungkus untuk sebuah Array, yang akan membuat Array menjadi lebih sakti.
Maksudnya bagaimana? lihat kode pada bagian mode berikut ini
Pada data model tersebut, kita mempunyai sebuah array di dalam array, ada array numeric yang didalamnya ada array associative. Nah kita akan membungkus array tersebut agar menjadi sebuah Collection.
Jika pada dokumentasi Laravel nya, di dalam Laravel menyediakan sebuah Collection yang merupakan pembungkus dari arrays of data. Sebagai contoh, lihat kode berikut ini. Kita akan menggunakan helper collect untuk membuat sebuah instance collection baru dari array kemudian menjalankan function strtoupper pada setiap element dan menghapus semua element kosong:
Seperti yang dijelaskan sebelumnya, helper collect akan mengembalikan sebuah namespace Illuminate\Support\Collection instance untuk memberikan array. Jadi, untuk membuat sebuah collection cukup simpel seperti kode berikut ini:
Dengan mengubah array kita menjadi collection, maka array kita sekarang dapat menjalankan method-method yang tersedia pada collection. Berikut adalah list-list method yang tersedia pada Collection.
Nah, berhubung array yang di convert menjadi collection dapat menjalankan method-method. Kita akan menggunakan beberapa method keren pada collection seperti first dan firstWhere.
Method first ini berfungsi untuk mencari element yang pertama, jika method firstWhere untuk mencari element yang pertama ketemu dengan sebuah kondisi.
Setelah memahami mengapa kita perlu mengubah array menjadi collection, selanjutnya kita akan ubah data array pada post model yang sudah kita buat sebelumnya agar menjadi sebuah collection di file app\Models\Post.php
Catatan: Tips Object Oriented Programming!
Perhatikan penulisan pemanggilan sebuah method yang static
php
static::method();
Keyword static didepan, merupakan teknik penulisan untuk pemanggilan method yang static, namun jika variabel teknik penulisan nya adalah
php
self::$property;
php
<?phpnamespace App\Models;class Post{ private static $blog_posts = [ ... ]; public static function all() { return collect(self::$blog_posts); } public static function find($slug) { $posts = static::all(); // $post = []; // foreach ($posts as $p) { // if ($p['slug'] === $slug) { // $post = $p; // } // } return $posts->firstWhere('slug', $slug); }}
Bisa kalian lihat pada kode diatas tersebut, yang sebelumnya kita melakukan sebuah looping untuk mencari data berdasarkan $slug di url atau route nya. Sekarang menjadi simpel dengan menggunakan method yang tersedia pada collection yaitu firstWhere.
Kode tersebut artinya sebagai berikut, ambil semua collection dari property $posts kemudian cari yang pertama kali ditemukan yang dimana slug nya = $slug.
Setelah 2 komponen selesai kita buta yaitu Model dan View, selanjutnya kita akan membuat 1 komponen lagi yaitu Controller agar paradigma MVC benar-benar kita gunakan. Jika kalian lihat sekarang pada bagian routes nya, yang menangani proses itu masih routes nya itu sendiri.
Nah, seharusnya proses tersebut di handle atau diurus oleh Controller jika kita ingin menerapkan konsep paradgima MVC. Karena memang yang namanya Controller itu adalah yang menangani atau mengendalikan nampilin atau View yang mana dan ngambil Model dari mana.
Jika diambil penjelasan Controller pada website resmi Laravel nya, Controller adalah dari pada kita mendefinisikan semua logic program kita saat menangani proses request atau closure
php
Route::get('', function() { // Anonymous function inilah yang dinamakan closure})
Dari pada kita bikin sebagai closure di dalam routes file kita, kita bisa merapihkan hal tersebut menggunakan sebuah Class Controller. Controller bisa menggabungkan atau mengelompokan request yang serupa yang saling terkait untuk menangani logic nya dalam sebuah Class. Contohnya, jika kita ingin menangani halaman semua postingan dan yang menangani single postingan. Nah, hal tersebut cocok dijadikan satu Controller karena dua proses tersebut dihandle oleh Controller Post nantinya.
Untuk pembuatan atau penulisan sebuah Controller, kita bisa bikin sebuah file yang tersimpan di app/Http/Controllers/ atau namespace folder ini App\Http\Controllers\ kemudian isian dari file tersebut membuat sebuah class yang format penulisan nya adalah Nama kemudian di ikuti dengan kata Controller sehingga menjadi IniNamaController atau pada studi kasus kita PostController dan class tersebut meng-extends atau mewarisi class bawaan laravel yaitu Controller. Nah, didalam class tersebut nantinya mempunyai berbagai macam method untuk menangani tiap-tiap logic nya. Contoh penulisan Controller pada dokumentasi resmi Laravel nya sebagai berikut
php
<?phpnamespace App\Http\Controllers;use App\Http\Controllers\Controller;use App\Models\User;class UserController extends Controller{ /** * Show the profile for a given user. * * @param int $id * @return \Illuminate\View\View */ public function show($id) { return view('user.profile', [ 'user' => User::findOrFail($id) ]); }}
Nah, nantinya kita akan membuat 2 buah method didalam class Controller tersebut, 1 untuk menangani semua postingan dan 1 lagi untuk menangani sebuah postingan atau single post nya. Nah, setelah controller jadi, maka si routes nya tidak mempunyai lagi closure, namun kita tulis seperti ini saja
php
use App\Http\Controllers\UserController;Route::get('/user/{id}', [UserController::class, 'show']);
Setelah mengetahui mengapa menggunakan Controller dan bagaimana cara membuatnya, sekarang saatnya kita menerapkan nya. Sekarang kalian buat sebuah Controller menggunakan perintah berikut ini:
bash
php artisan make:controller PostController
Maka sekarang terdapat sebuah file baru di app/Http/Controllers/PostController.php dengan isian seperti berikut:
Catatan:
Abaikan terlebih dahulu bagian
php
use Illuminate\Http\Request;
Karena hal tersebut nantinya akan berguna untuk menangani request jika kita mempunyai form atau data di URL sebagai request.
Setelah Controller dibuat, selanjutnya kita akan membuat method yang namanya index sebagai method default nya.
php
<?phpnamespace App\Http\Controllers;use Illuminate\Http\Request;//use App\Models\Post;class PostController extends Controller{ public function index() { return view('posts', [ "title" => "Posts", // Menggunakan use //"posts" => Post::all() // Menggunakan expand class "posts" => \App\Models\Post::all() ]); }}
Setelah Controller ready atau siap, sekarang kita benarkan penulisan routes nya agar tidak lagi menggunakan closure, sehingga yang tadinya penulisan nya seperti ini:
Setelah sebelumnya kita sudah menerapkan controller untuk menangani halaman semua postingan, selanjutnya kita buat sebuah method baru dengan nama show untuk menangani single post nya.
php
<?phpnamespace App\Http\Controllers;use Illuminate\Http\Request;//use App\Models\Post;class PostController extends Controller{ public function index() { return view('posts', [ "title" => "Posts", // Menggunakan use //"posts" => Post::all() // Menggunakan expand class "posts" => \App\Models\Post::all() ]); } public function show($slug) { return view('post', [ 'title' => 'Single Post', 'post' => \App\Models\Post::find($slug) ]); }}
Nah, sekarang kita ubah bagian kode routes yang menggunakan closure pada route yang menangani single post nya agar menggunakan controller nya
php
Route::get('/posts', [PostController::class, 'index']);// Halaman Single PostRoute::get('posts/{slug}', [PostController::class, 'show']);