{"id":1090,"date":"2025-11-04T04:30:05","date_gmt":"2025-11-04T04:30:05","guid":{"rendered":"https:\/\/gurututorku.com\/blog\/?p=1090"},"modified":"2026-02-02T02:59:04","modified_gmt":"2026-02-02T02:59:04","slug":"tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita","status":"publish","type":"post","link":"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/","title":{"rendered":"Tutorial Laravel 12 &#8211; Membuat Website Blog Berita &#8211; Bagian #3 (Relasi Kategori dan Tag Berita)"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>3. Menambahkan Fitur Kategori &amp; Tag pada Berita (Laravel)<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pada tahap ini, kita akan menambahkan <strong>kategori (one-to-many)<\/strong> dan <strong>tag (many-to-many)<\/strong> pada fitur berita (posts), sehingga konten menjadi lebih terorganisir dan profesional seperti portal berita sungguhan.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Tujuan Pembelajaran<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Setelah menyelesaikan bagian ini, peserta mampu:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Membuat tabel <strong>categories<\/strong> dan <strong>tags<\/strong><\/li>\n\n\n\n<li>Menghubungkan <strong>Post &#x2194; Category &#x2194; Tag<\/strong><\/li>\n\n\n\n<li>Menampilkan kategori &amp; tag di halaman berita<\/li>\n\n\n\n<li>Mengelola kategori dan tag saat tambah &amp; edit berita<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>A. Membuat Model &amp; Migration<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>1. Generate Model dan Migration<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">php artisan make:model Category -m<br>php artisan make:model Tag -m<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>2. Migration Tabel Categories<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Edit file <code>create_categories_table.php<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Schema::create('categories', function (Blueprint $table) {<br>  &nbsp; $table-&gt;id();<br>  &nbsp; $table-&gt;string('name');<br>  &nbsp; $table-&gt;timestamps();<br>});<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>3. Migration Tabel Tags<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Edit file <code>create_tags_table.php<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Schema::create('tags', function (Blueprint $table) {<br>  &nbsp; $table-&gt;id();<br>  &nbsp; $table-&gt;string('name');<br>  &nbsp; $table-&gt;timestamps();<br>});<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>B. Menambahkan Relasi ke Posts<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>1. Buat Migration Relasi<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">php artisan make:migration add_category_id_to_posts_table --table=posts<br>php artisan make:migration create_post_tag_table --create=post_tag<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>2. Tambahkan Category ke Posts<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">File <code>add_category_id_to_posts_table.php<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Schema::table('posts', function (Blueprint $table) {<br>  &nbsp; $table-&gt;foreignId('category_id')-&gt;nullable()-&gt;constrained('categories')-&gt;onDelete('set null');<br>});<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>3. Tabel Pivot Post\u2013Tag<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">File <code>create_post_tag_table.php<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Schema::create('post_tag', function (Blueprint $table) {<br>  &nbsp; $table-&gt;id();<br>  &nbsp; $table-&gt;foreignId('post_id')-&gt;constrained()-&gt;onDelete('cascade');<br>  &nbsp; $table-&gt;foreignId('tag_id')-&gt;constrained()-&gt;onDelete('cascade');<br>});<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>4. Jalankan Migration<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">php artisan migrate<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>C. Menambahkan Relasi di Model<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>1. Model Post<\/strong> : Post.php<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">public function category()<br>{<br>  &nbsp; return $this-&gt;belongsTo(Category::class);<br>}<br><br>public function tags()<br>{<br>  &nbsp; return $this-&gt;belongsToMany(Tag::class);<br>}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>2. Model Category : <\/strong>Category.php<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;?php<br>namespace App\\Models;<br>use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;<br>use Illuminate\\Database\\Eloquent\\Model;<br><br>class Category extends Model<br>{<br>  &nbsp; use HasFactory;<br>  &nbsp; protected $fillable = [<br>  &nbsp; &nbsp; &nbsp; 'name',<br>  &nbsp; ];<br>  &nbsp; \/\/ Relasi: satu kategori punya banyak post<br>  &nbsp; public function posts()<br>  &nbsp; {<br>  &nbsp; &nbsp; &nbsp; return $this-&gt;hasMany(Post::class);<br>  &nbsp; }<br>}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Model Tag : <\/strong>Tag.php<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;?php<br>namespace App\\Models;<br>use Illuminate\\Database\\Eloquent\\Factories\\HasFactory;<br>use Illuminate\\Database\\Eloquent\\Model;<br><br>class Tag extends Model<br>{<br>  &nbsp; use HasFactory;<br>  &nbsp; protected $fillable = [<br>  &nbsp; &nbsp; &nbsp; 'name',<br>  &nbsp; ];<br>  &nbsp; \/\/ Relasi: satu tag bisa dimiliki banyak post<br>  &nbsp; public function posts()<br>  &nbsp; {<br>  &nbsp; &nbsp; &nbsp; return $this-&gt;belongsToMany(Post::class);<br>  &nbsp; }<br>}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>D. Ubah Form Tambah Berita<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>1. Dropdown Kategori<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tambahkan dropdown kategori dan checkbox tag.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;div class=\"mb-3\"&gt;<br>  &nbsp; &lt;label&gt;Kategori&lt;\/label&gt;<br>  &nbsp; &lt;select name=\"category_id\" class=\"form-control\"&gt;<br>  &nbsp; &nbsp; &nbsp; &lt;option value=\"\"&gt;-- Pilih Kategori --&lt;\/option&gt;<br>  &nbsp; &nbsp; &nbsp; @foreach($categories as $category)<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;option value=\"{{ $category-&gt;id }}\"&gt;{{ $category-&gt;name }}&lt;\/option&gt;<br>  &nbsp; &nbsp; &nbsp; @endforeach<br>  &nbsp; &lt;\/select&gt;<br>&lt;\/div&gt;<br><br>&lt;div class=\"mb-3\"&gt;<br>  &nbsp; &lt;label&gt;Tag&lt;\/label&gt;&lt;br&gt;<br>  &nbsp; @foreach($tags as $tag)<br>  &nbsp; &nbsp; &nbsp; &lt;label&gt;&lt;input type=\"checkbox\" name=\"tags[]\" value=\"{{ $tag-&gt;id }}\"&gt; {{ $tag-&gt;name }}&lt;\/label&gt;&lt;br&gt;<br>  &nbsp; @endforeach<br>&lt;\/div&gt;<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>E. Update PostController<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>1. Import Model<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Lalu di PostController, tambahkan:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;?php<br>namespace App\\Http\\Controllers;<br>use App\\Models\\Post;<br>use App\\Models\\Category; \/\/ Jika perlu kategori<br>use App\\Models\\Tag;<br>use Illuminate\\Http\\Request;<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>2. Method create()<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Lalu pada create() di PostController, tambahkan:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">  &nbsp; public function create()<br>  &nbsp; {<br>  &nbsp; &nbsp; &nbsp; $categories = Category::orderBy('name')-&gt;get();<br>  &nbsp; &nbsp; &nbsp; $tags = Tag::orderBy('name')-&gt;get();<br>  &nbsp; &nbsp; &nbsp; \/\/ cara lain jika juga butuh tags:<br>  &nbsp; &nbsp; &nbsp; \/\/$tags = \\App\\Models\\Tag::orderBy('name')-&gt;get();<br>  &nbsp; &nbsp; &nbsp; return view('posts.create', compact('categories','tags'));<br>&nbsp; &nbsp; }<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>3. Method store()<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Lalu pada store() di PostController, tambahkan:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">public function store(Request $request)<br>  &nbsp; {<br>  &nbsp; &nbsp; &nbsp; \/\/ 1. Validasi input<br>  &nbsp; &nbsp; &nbsp; $request-&gt;validate([<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'title' &nbsp; &nbsp; &nbsp; =&gt; 'required|string|max:255',<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'content' &nbsp; &nbsp; =&gt; 'required|string',<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'author' &nbsp; &nbsp; &nbsp;=&gt; 'nullable|string|max:100',<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'category_id' =&gt; 'nullable|exists:categories,id',<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'tags' &nbsp; &nbsp; &nbsp; &nbsp;=&gt; 'nullable|array',<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'tags.*' &nbsp; &nbsp; &nbsp;=&gt; 'exists:tags,id',<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'thumbnail' &nbsp; =&gt; 'nullable|image|mimes:jpeg,png,jpg|max:2048',<br>  &nbsp; &nbsp; &nbsp; ]);<br>  &nbsp; &nbsp; &nbsp; \/\/ 2. Ambil data utama<br>  &nbsp; &nbsp; &nbsp; $data = $request-&gt;only(['title', 'content', 'author', 'category_id']);<br>  &nbsp; &nbsp; &nbsp; \/\/ 3. Upload thumbnail jika ada<br>  &nbsp; &nbsp; &nbsp; if ($request-&gt;hasFile('thumbnail')) {<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $path = $request-&gt;file('thumbnail')-&gt;store('thumbnails', 'public');<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $data['thumbnail'] = $path;<br>  &nbsp; &nbsp; &nbsp; }<br>  &nbsp; &nbsp; &nbsp; \/\/ 4. Simpan post baru<br>  &nbsp; &nbsp; &nbsp; $post = \\App\\Models\\Post::create($data);<br>  &nbsp; &nbsp; &nbsp; \/\/ 5. Simpan relasi tags ke tabel pivot<br>  &nbsp; &nbsp; &nbsp; if ($request-&gt;has('tags')) {<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $post-&gt;tags()-&gt;sync($request-&gt;tags);<br>  &nbsp; &nbsp; &nbsp; }<br>  &nbsp; &nbsp; &nbsp; \/\/ 6. Redirect dengan pesan sukses<br>  &nbsp; &nbsp; &nbsp; return redirect()<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;route('posts.index')<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;with('success', 'Berita berhasil ditambahkan!');<br>  &nbsp; }<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">F. Halaman Detail \/ Show Berita<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ubah script di edit.blade.php, menjadi :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@extends('layouts.app')<br>@section('content')<br>&lt;div class=\"container\"&gt;<br>  &nbsp; &lt;div class=\"card shadow-sm mb-4\"&gt;<br>  &nbsp; &nbsp; &nbsp; {{-- Thumbnail --}}<br>  &nbsp; &nbsp; &nbsp; @if($post-&gt;thumbnail)<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;img src=\"{{ asset('storage\/' . $post-&gt;thumbnail) }}\"<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;alt=\"{{ $post-&gt;title }}\"<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;class=\"card-img-top\"<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;style=\"max-height: 400px; object-fit: cover;\"&gt;<br>&nbsp; &nbsp; &nbsp; &nbsp; @endif<br><br>  &nbsp; &nbsp; &nbsp; &lt;div class=\"card-body\"&gt;<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {{-- Judul --}}<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;h2 class=\"card-title\"&gt;{{ $post-&gt;title }}&lt;\/h2&gt;<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {{-- Info tambahan --}}<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class=\"text-muted mb-3\"&gt;<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;small&gt;<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Oleh &lt;strong&gt;{{ $post-&gt;author ?? 'Admin' }}&lt;\/strong&gt; |<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {{ $post-&gt;created_at-&gt;format('d M Y') }}<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/small&gt;&lt;br&gt;<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {{-- Kategori --}}<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @if($post-&gt;category)<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class=\"badge bg-primary\"&gt;Kategori: {{ $post-&gt;category-&gt;name }}&lt;\/span&gt;<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @endif<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/div&gt;<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {{-- Isi berita --}}<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class=\"card-text\" style=\"white-space: pre-line;\"&gt;<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {!! nl2br(e($post-&gt;content)) !!}<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/div&gt;<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {{-- Tag --}}<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @if($post-&gt;tags-&gt;count() &gt; 0)<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class=\"mt-4\"&gt;<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;strong&gt;Tags:&lt;\/strong&gt;&lt;br&gt;<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @foreach($post-&gt;tags as $tag)<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class=\"badge bg-secondary\"&gt;{{ $tag-&gt;name }}&lt;\/span&gt;<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @endforeach<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/div&gt;<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @endif<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {{-- Tombol aksi --}}<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class=\"mt-4\"&gt;<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;a href=\"{{ route('posts.index') }}\" class=\"btn btn-outline-secondary\"&gt;Kembali&lt;\/a&gt;<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/div&gt;<br>  &nbsp; &nbsp; &nbsp; &lt;\/div&gt;<br>  &nbsp; &lt;\/div&gt;<br>&lt;\/div&gt;<br>@endsection<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>G. Edit &amp; Update Berita<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ubah function edit() dan update() di PostController.php :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">public function edit($id)<br>  &nbsp; {<br>  &nbsp; &nbsp; &nbsp; \/\/ Ambil data post dengan relasi category dan tags<br>  &nbsp; &nbsp; &nbsp; $post = Post::with(['category', 'tags'])-&gt;findOrFail($id);<br>  &nbsp; &nbsp; &nbsp; \/\/ Ambil semua kategori dan tags untuk form<br>  &nbsp; &nbsp; &nbsp; $categories = Category::all();<br>  &nbsp; &nbsp; &nbsp; $tags = Tag::all();<br>  &nbsp; &nbsp; &nbsp; return view('posts.edit', compact('post', 'categories', 'tags'));<br>  &nbsp; }<br>\/\/\u2014-----------------------<br>public function update(Request $request, $id)<br>  &nbsp; {<br>  &nbsp; &nbsp; &nbsp; \/\/ 1. Validasi input<br>  &nbsp; &nbsp; &nbsp; $request-&gt;validate([<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'title' =&gt; 'required|string|max:255',<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'content' =&gt; 'required|string',<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'author' =&gt; 'nullable|string|max:100',<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'category_id' =&gt; 'nullable|exists:categories,id',<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'tags' =&gt; 'nullable|array',<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'tags.*' =&gt; 'exists:tags,id',<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'thumbnail' =&gt; 'nullable|image|mimes:jpeg,png,jpg|max:2048',<br>  &nbsp; &nbsp; &nbsp; ]);<br>  &nbsp; &nbsp; &nbsp; \/\/ 2. Temukan post<br>  &nbsp; &nbsp; &nbsp; $post = Post::findOrFail($id);<br>  &nbsp; &nbsp; &nbsp; \/\/ 3. Ambil data utama<br>  &nbsp; &nbsp; &nbsp; $data = $request-&gt;only(['title', 'content', 'author', 'category_id']);<br>  &nbsp; &nbsp; &nbsp; \/\/ 4. Jika upload thumbnail baru<br>  &nbsp; &nbsp; &nbsp; if ($request-&gt;hasFile('thumbnail')) {<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/\/ Hapus file lama (jika ada)<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ($post-&gt;thumbnail &amp;&amp; \\Storage::disk('public')-&gt;exists($post-&gt;thumbnail)) {<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \\Storage::disk('public')-&gt;delete($post-&gt;thumbnail);<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/\/ Upload file baru<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $path = $request-&gt;file('thumbnail')-&gt;store('thumbnails', 'public');<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $data['thumbnail'] = $path;<br>  &nbsp; &nbsp; &nbsp; }<br>  &nbsp; &nbsp; &nbsp; \/\/ 5. Update data post<br>  &nbsp; &nbsp; &nbsp; $post-&gt;update($data);<br>  &nbsp; &nbsp; &nbsp; \/\/ 6. Update relasi tags<br>  &nbsp; &nbsp; &nbsp; if ($request-&gt;has('tags')) {<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $post-&gt;tags()-&gt;sync($request-&gt;tags);<br>  &nbsp; &nbsp; &nbsp; } else {<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $post-&gt;tags()-&gt;detach(); \/\/ kalau tidak ada tag, kosongkan<br>  &nbsp; &nbsp; &nbsp; }<br>  &nbsp; &nbsp; &nbsp; \/\/ 7. Redirect dengan pesan sukses<br>  &nbsp; &nbsp; &nbsp; return redirect()<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;route('posts.index')<br>  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt;with('success', 'Berita berhasil diperbarui!');<br>  &nbsp; }<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Pembuatan web berita menggunakan Laravel diawali dengan tahap persiapan yang mencakup perencanaan struktur aplikasi, instalasi lingkungan pengembangan, serta konfigurasi awal framework. Laravel dipilih karena menyediakan sistem MVC (Model-View-Controller) yang terorganisir, fitur autentikasi bawaan, dan kemudahan dalam membuat CRUD (Create, Read, Update, Delete).<\/p>\n","protected":false},"author":1,"featured_media":824,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11,38],"tags":[35,140,141,142,22,138,139,143,144],"class_list":["post-1090","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-php-framework-laravel","category-tutorial-programming","tag-laravel-controller","tag-laravel-model","tag-laravel-route","tag-laravel-view-blade","tag-php-framework","tag-tutorial-laravel-12","tag-tutorial-laravel-migrate","tag-tutorial-laravel-mysql","tag-web-berita-laravel"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v23.7 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Tutorial Laravel 12 - Membuat Website Blog Berita - Bagian #3 (Relasi Kategori dan Tag Berita) - Gurututorku<\/title>\n<meta name=\"description\" content=\"laravel controller, laravel model, laravel route, laravel view blade, php framework, tutorial laravel 12, tutorial laravel migrate, tutorial laravel mysql, web berita laravel\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Tutorial Laravel 12 - Membuat Website Blog Berita - Bagian #3 (Relasi Kategori dan Tag Berita) - Gurututorku\" \/>\n<meta property=\"og:description\" content=\"laravel controller, laravel model, laravel route, laravel view blade, php framework, tutorial laravel 12, tutorial laravel migrate, tutorial laravel mysql, web berita laravel\" \/>\n<meta property=\"og:url\" content=\"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/\" \/>\n<meta property=\"og:site_name\" content=\"Gurututorku\" \/>\n<meta property=\"article:published_time\" content=\"2025-11-04T04:30:05+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-02-02T02:59:04+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/gurututorku.com\/blog\/wp-content\/uploads\/2024\/11\/laravel.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1000\" \/>\n\t<meta property=\"og:image:height\" content=\"750\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"gtadmin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"gtadmin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/\"},\"author\":{\"name\":\"gtadmin\",\"@id\":\"https:\/\/gurututorku.com\/blog\/#\/schema\/person\/6c85586545a9930343cd35e9bf4bd9a2\"},\"headline\":\"Tutorial Laravel 12 &#8211; Membuat Website Blog Berita &#8211; Bagian #3 (Relasi Kategori dan Tag Berita)\",\"datePublished\":\"2025-11-04T04:30:05+00:00\",\"dateModified\":\"2026-02-02T02:59:04+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/\"},\"wordCount\":202,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/gurututorku.com\/blog\/#\/schema\/person\/6c85586545a9930343cd35e9bf4bd9a2\"},\"image\":{\"@id\":\"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/gurututorku.com\/blog\/wp-content\/uploads\/2024\/11\/laravel.png\",\"keywords\":[\"laravel controller\",\"laravel model\",\"laravel route\",\"laravel view blade\",\"php framework\",\"tutorial laravel 12\",\"tutorial laravel migrate\",\"tutorial laravel mysql\",\"web berita laravel\"],\"articleSection\":[\"PHP Framework Laravel\",\"Tutorial Programming\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/\",\"url\":\"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/\",\"name\":\"Tutorial Laravel 12 - Membuat Website Blog Berita - Bagian #3 (Relasi Kategori dan Tag Berita) - Gurututorku\",\"isPartOf\":{\"@id\":\"https:\/\/gurututorku.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/gurututorku.com\/blog\/wp-content\/uploads\/2024\/11\/laravel.png\",\"datePublished\":\"2025-11-04T04:30:05+00:00\",\"dateModified\":\"2026-02-02T02:59:04+00:00\",\"description\":\"laravel controller, laravel model, laravel route, laravel view blade, php framework, tutorial laravel 12, tutorial laravel migrate, tutorial laravel mysql, web berita laravel\",\"breadcrumb\":{\"@id\":\"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/#primaryimage\",\"url\":\"https:\/\/gurututorku.com\/blog\/wp-content\/uploads\/2024\/11\/laravel.png\",\"contentUrl\":\"https:\/\/gurututorku.com\/blog\/wp-content\/uploads\/2024\/11\/laravel.png\",\"width\":1000,\"height\":750},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/gurututorku.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Tutorial Laravel 12 &#8211; Membuat Website Blog Berita &#8211; Bagian #3 (Relasi Kategori dan Tag Berita)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/gurututorku.com\/blog\/#website\",\"url\":\"https:\/\/gurututorku.com\/blog\/\",\"name\":\"Gurututorku - Learning today success tomorrow\",\"description\":\"Kelas dan Kursus Programming, Design, Multimedia dan Tutorial IT lainnya.\",\"publisher\":{\"@id\":\"https:\/\/gurututorku.com\/blog\/#\/schema\/person\/6c85586545a9930343cd35e9bf4bd9a2\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/gurututorku.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/gurututorku.com\/blog\/#\/schema\/person\/6c85586545a9930343cd35e9bf4bd9a2\",\"name\":\"gtadmin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/gurututorku.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/gurututorku.com\/blog\/wp-content\/uploads\/2024\/11\/cropped-gurututorku-favicon.png\",\"contentUrl\":\"https:\/\/gurututorku.com\/blog\/wp-content\/uploads\/2024\/11\/cropped-gurututorku-favicon.png\",\"width\":512,\"height\":512,\"caption\":\"gtadmin\"},\"logo\":{\"@id\":\"https:\/\/gurututorku.com\/blog\/#\/schema\/person\/image\/\"},\"sameAs\":[\"http:\/\/gurututorku.com\/blog\"],\"url\":\"https:\/\/gurututorku.com\/blog\/author\/gtadmin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Tutorial Laravel 12 - Membuat Website Blog Berita - Bagian #3 (Relasi Kategori dan Tag Berita) - Gurututorku","description":"laravel controller, laravel model, laravel route, laravel view blade, php framework, tutorial laravel 12, tutorial laravel migrate, tutorial laravel mysql, web berita laravel","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/","og_locale":"en_US","og_type":"article","og_title":"Tutorial Laravel 12 - Membuat Website Blog Berita - Bagian #3 (Relasi Kategori dan Tag Berita) - Gurututorku","og_description":"laravel controller, laravel model, laravel route, laravel view blade, php framework, tutorial laravel 12, tutorial laravel migrate, tutorial laravel mysql, web berita laravel","og_url":"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/","og_site_name":"Gurututorku","article_published_time":"2025-11-04T04:30:05+00:00","article_modified_time":"2026-02-02T02:59:04+00:00","og_image":[{"width":1000,"height":750,"url":"https:\/\/gurututorku.com\/blog\/wp-content\/uploads\/2024\/11\/laravel.png","type":"image\/png"}],"author":"gtadmin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"gtadmin","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/#article","isPartOf":{"@id":"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/"},"author":{"name":"gtadmin","@id":"https:\/\/gurututorku.com\/blog\/#\/schema\/person\/6c85586545a9930343cd35e9bf4bd9a2"},"headline":"Tutorial Laravel 12 &#8211; Membuat Website Blog Berita &#8211; Bagian #3 (Relasi Kategori dan Tag Berita)","datePublished":"2025-11-04T04:30:05+00:00","dateModified":"2026-02-02T02:59:04+00:00","mainEntityOfPage":{"@id":"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/"},"wordCount":202,"commentCount":0,"publisher":{"@id":"https:\/\/gurututorku.com\/blog\/#\/schema\/person\/6c85586545a9930343cd35e9bf4bd9a2"},"image":{"@id":"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/#primaryimage"},"thumbnailUrl":"https:\/\/gurututorku.com\/blog\/wp-content\/uploads\/2024\/11\/laravel.png","keywords":["laravel controller","laravel model","laravel route","laravel view blade","php framework","tutorial laravel 12","tutorial laravel migrate","tutorial laravel mysql","web berita laravel"],"articleSection":["PHP Framework Laravel","Tutorial Programming"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/","url":"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/","name":"Tutorial Laravel 12 - Membuat Website Blog Berita - Bagian #3 (Relasi Kategori dan Tag Berita) - Gurututorku","isPartOf":{"@id":"https:\/\/gurututorku.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/#primaryimage"},"image":{"@id":"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/#primaryimage"},"thumbnailUrl":"https:\/\/gurututorku.com\/blog\/wp-content\/uploads\/2024\/11\/laravel.png","datePublished":"2025-11-04T04:30:05+00:00","dateModified":"2026-02-02T02:59:04+00:00","description":"laravel controller, laravel model, laravel route, laravel view blade, php framework, tutorial laravel 12, tutorial laravel migrate, tutorial laravel mysql, web berita laravel","breadcrumb":{"@id":"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/#primaryimage","url":"https:\/\/gurututorku.com\/blog\/wp-content\/uploads\/2024\/11\/laravel.png","contentUrl":"https:\/\/gurututorku.com\/blog\/wp-content\/uploads\/2024\/11\/laravel.png","width":1000,"height":750},{"@type":"BreadcrumbList","@id":"https:\/\/gurututorku.com\/blog\/tutorial-laravel-12-membuat-website-blog-berita-bagian-3-relasi-kategori-dan-tag-berita\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/gurututorku.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Tutorial Laravel 12 &#8211; Membuat Website Blog Berita &#8211; Bagian #3 (Relasi Kategori dan Tag Berita)"}]},{"@type":"WebSite","@id":"https:\/\/gurututorku.com\/blog\/#website","url":"https:\/\/gurututorku.com\/blog\/","name":"Gurututorku - Learning today success tomorrow","description":"Kelas dan Kursus Programming, Design, Multimedia dan Tutorial IT lainnya.","publisher":{"@id":"https:\/\/gurututorku.com\/blog\/#\/schema\/person\/6c85586545a9930343cd35e9bf4bd9a2"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/gurututorku.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/gurututorku.com\/blog\/#\/schema\/person\/6c85586545a9930343cd35e9bf4bd9a2","name":"gtadmin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/gurututorku.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/gurututorku.com\/blog\/wp-content\/uploads\/2024\/11\/cropped-gurututorku-favicon.png","contentUrl":"https:\/\/gurututorku.com\/blog\/wp-content\/uploads\/2024\/11\/cropped-gurututorku-favicon.png","width":512,"height":512,"caption":"gtadmin"},"logo":{"@id":"https:\/\/gurututorku.com\/blog\/#\/schema\/person\/image\/"},"sameAs":["http:\/\/gurututorku.com\/blog"],"url":"https:\/\/gurututorku.com\/blog\/author\/gtadmin\/"}]}},"_links":{"self":[{"href":"https:\/\/gurututorku.com\/blog\/wp-json\/wp\/v2\/posts\/1090","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gurututorku.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gurututorku.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gurututorku.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gurututorku.com\/blog\/wp-json\/wp\/v2\/comments?post=1090"}],"version-history":[{"count":24,"href":"https:\/\/gurututorku.com\/blog\/wp-json\/wp\/v2\/posts\/1090\/revisions"}],"predecessor-version":[{"id":1496,"href":"https:\/\/gurututorku.com\/blog\/wp-json\/wp\/v2\/posts\/1090\/revisions\/1496"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gurututorku.com\/blog\/wp-json\/wp\/v2\/media\/824"}],"wp:attachment":[{"href":"https:\/\/gurututorku.com\/blog\/wp-json\/wp\/v2\/media?parent=1090"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gurututorku.com\/blog\/wp-json\/wp\/v2\/categories?post=1090"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gurututorku.com\/blog\/wp-json\/wp\/v2\/tags?post=1090"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}