laravel 9 posts with tags many to many relationships example

In this tutorial we will see how to add tags in posts using many to many relationships.


Create Post Modal Migration Controller and Route

run below command to create post modal, migration and controller.

php artisan make:model Post -mcr

create_posts_table.php

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->string('slug');
        $table->longText('description');
        $table->timestamps();
    });
}


Create Tags Modal and Migration

php artisan make:model Tag -m

create_tags_table.php

public function up()
{
    Schema::create('tags', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->timestamps();
    });
}


Create Post Tag Pivot Table

Run below command to create post tag pivot table.

php artisan make:migration CreatePostTagTable

post_tag_table.php

public function up()
{
    Schema::create('post_tag', function (Blueprint $table) {
        $table->id();
        $table->foreignId('post_id')->constrained()->onDelete('cascade');
        $table->foreignId('tag_id')->constrained()->onDelete('cascade');
        $table->timestamps();
    });
}

web.php

Route::resource('posts', PostController::class);


Create Tags Seeder

php artisan make:seeder TagSeeder

seeders/TagSeeder.php

<?php

namespace Database\Seeders;

use App\Models\Tag;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class TagSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $data = [
            [
                'name' => 'Laravel',
                'created_at' => now(),
                'updated_at' => now()
            ],
            [
                'name' => 'Node JS',
                'created_at' => now(),
                'updated_at' => now()
            ],
            [
                'name' => 'Python',
                'created_at' => now(),
                'updated_at' => now()
            ],
            [
                'name' => 'Java',
                'created_at' => now(),
                'updated_at' => now()
            ],
            [
                'name' => 'React',
                'created_at' => now(),
                'updated_at' => now()
            ],
        ];
        Tag::insert($data);
    }
}

seeders/DatabaseSeeder.php

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call(TagSeeder::class);
        $this->command->info('Tag Seeder created.');
    }
}


Add Tag Many to Many Relationships in Modal

Models/Post.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'title',
        'slug',
        'description',
    ];

    public function tags()
    {
        return $this->belongsToMany(Tag::class)->as('tags');
    }
}


Models/Tag.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Tag extends Model
{
    use HasFactory;

    protected $fillable = ['name'];

    public function posts()
    {
        return $this->belongsToMany(Post::class);
    }
}


Attach Tags in Post Controller

Attach Tags in PostController.php using many to many relationships.

app/Http/Controllers/PostController.php

<?php

namespace App\Http\Controllers;

use App\Models\Post;
use App\Models\Tag;
use Illuminate\Http\Request;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $posts = Post::with(['tags'])->latest()->paginate(10);
        return view('posts.index', compact('posts'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $tags = Tag::all();
        return view('posts.create', compact('tags'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'slug' => 'required|string|max:255',
            'description' => 'required'
        ]);
        $post = Post::create([
            'title' => $request->title,
            'slug' => \Str::slug($request->slug),
            'description' => $request->description,
        ]);

        if ($request->has('tags')) {
            $post->tags()->attach($request->tags);
        }

       return redirect()->route('posts.index')->with('status', 'Post Created Successfully');
    }
}


Add Tags in Blade File

views/posts/create.blade.php

<form method="POST" action="{{ route('posts.store') }}">
    @csrf
    <div class="mb-6">
        <label class="block">
            <span class="text-gray-700">Title</span>
            <input type="text" name="title"
                class="block w-full @error('title') border-red-500 @enderror mt-1 rounded-md" placeholder=""
                value="{{old('title')}}" />
        </label>
        @error('title')
        <div class="text-sm text-red-600">{{ $message }}</div>
        @enderror
    </div>
    <div class="mb-6">
        <label class="block">
            <span class="text-gray-700">Slug</span>
            <input type="text" name="slug" class="block w-full @error('slug') border-red-500 @enderror mt-1 rounded-md"
                placeholder="" value="{{old('slug')}}" />
        </label>
        @error('slug')
        <div class="text-sm text-red-600">{{ $message }}</div>
        @enderror
    </div>
    <div class="mb-6">
        <label class="block">
            <span class="text-gray-700">Tag</span>
            <select name="tags[]" class="block w-full mt-1" multiple>
                @foreach ($tags as $tag)
                <option value="{{ $tag->id }}">{{ $tag->name }}</option>
                @endforeach
            </select>
        </label>
    </div>
    <div class="mb-6">
        <label class="block">
            <span class="text-gray-700">Description</span>
            <textarea " class="block w-full mt-1 rounded-md " name="description"
                rows="3">{{old('description')}}</textarea>
        </label>
        @error('description')
        <div class="text-sm text-red-600">{{ $message }}</div>
        @enderror
    </div>
    <button type="submit" class="text-white bg-blue-600  rounded text-sm px-5 py-2.5">Submit</button>

</form>
laravel many to many tags store

laravel many to many tags store


Show Posts Tags

views/posts/index.blade.php

<table class="w-full text-sm text-left text-gray-500">
    <thead class="text-xs text-gray-700 uppercase bg-gray-50">
        <tr>
            <th scope="col" class="px-6 py-3">
                #
            </th>
            <th scope="col" class="px-6 py-3">
                Name
            </th>
            <th scope="col" class="px-6 py-3">
                Tags
            </th>
        </tr>
    </thead>
    <tbody>
        @foreach ($posts as $post)
        <tr class="bg-white border-b">
            <th scope="row" class="px-6 py-4 font-medium text-gray-900">
                {{ $post->id }}
            </th>
            <td class="px-6 py-4">
                {{ $post->title }}
            </td>
            <td class="px-6 py-4">
                @foreach ($post->tags as $tag)
                {{ $tag->name }}
                @endforeach
            </td>
        </tr>
        @endforeach
    </tbody>
</table>
laravel 9 many to many tags example

laravel 9 many to many tags example


Read Also

Laravel 9 Add Simple Sidebar with Tailwind CSS Example

How to Use Carousel Slider in Laravel 9 Example

Laravel 9 Insert Category in Posts CRUD Example

How to Use Ckeditor 5 in Laravel 9 Vite with Tailwind CSS

Laravel 9 Simple Image Upload in Ckeditor 5 Example

Laravel 9 Flash Message Timeout and Hide Message Example

Install & Setup Markdown Editor in Laravel 9

Nuxt 3 Data Fetching Using Laravel 9 Api Example

Laravel 9 Image Upload with Preview using Tailwind CSS & Alpine JS

Laravel 9 with Tailwind CSS Form Validation Example

Laravel 9 Backend Api Connect with Vue 3 Using Axios Example

Laravel 9 Authentication with Next js Example

Laravel 9 Sanctum Authentication with Nuxt JS Example

Laravel 9 Simple Search with Pagination Example

Laravel 9 Install Setup TALL(Tailwind, Alpinejs, Livewire) Admin Panel

How to Fix and Clean Code Style in laravel 9

Laravel 9 Image File Upload Example

3 Way to Create Slug in Laravel 9 without Package

How to Add Dark Mode in Laravel 9 with Tailwind CSS


Tags: