Suppose a tag has many posts and a post is also associatd with many tags.
Hence we can create tag_post table ( which is also called as pivot table ) to establish this relationship between tags and posts table.
This type of relationship is called as many to many.
tag_post ( pivot table )
- id
- tag_id
- post_id
- timestamps
tags ( parent table )
- id
- title
- timestamps
posts ( parent table )
- id
- title
- timestamps
Now the process for code setup of this type relationship is mentioned below step by step
Step 01: Migration setup for tag_post table will be like below
// artisan command
php artisan make:migration create_tag_post_table
// migration for tag_post public function up() { Schema::create('tag_post', function (Blueprint $table) { $table->id(); $table->foreignId('tag_id')->constrained(); $table->foreignId('post_id')->constrained(); $table->timestamps(); }); }
Step 02: Model setup for Tag.php will be like below
namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Tag extends Model { use HasFactory; protected $fillable = ['title']; public function posts() { return $this->belongsToMany(Post::class); } }
Step 03: Model setup for Post.php will be like below.
We need to have posts migration for creating tables in the database also. We can use artisan command like this
php artisan make:migration create_posts_table
namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Post extends Model { use HasFactory; protected $fillable = ['title']; public function tags() { return $this->belongsToMany(Tag::class); } }
Step 04: Now, In PostController.php creating, updating, displaying and deleting rows using this relationship
function create() { // $tags = ['messi', 'ronaldo', 'mabappe']; $post = Post::create(['title' => 'the three']); foreach( $tags as $tag ) { $post->tags()->create(['title' => $tag]); } //or foreach( $tags as $tag ) { $insertedTags[] = Tag::create(['title' => $tag]); } $post->tags()->attach($insertedTags); return redirect()->route('posts.index'); } function index() { $posts = Post::with('tags')->get(); dd($posts); } function edit(Post $post) { // $post->load('tags'); $post->update(['title' => 'test title 2']); // $post->tags->each->delete(); $count = 1; foreach( $post->tags as $tag ) { $tag->update([ 'title' => 'updated tag '.$count ]); $count++; } // or $tags = ['alonso', 'raikonen', 'vatel']; foreach( $tags as $tag ) { $insertedTags[] = Tag::create(['title' => $tag]); } $post->tags()->sync($insertedTags); return redirect()->route('posts.index'); } function delete(Post $post) { $post->load('tags'); //dd($post); // checking if there are any tags associated with the post..
// if absence of related records is a possibility if ($post->tags->isNotEmpty()) { $post->tags()->detach(); } $post->delete(); return redirect()->route('posts.index'); }
Step 06: In routes/web.php we need to setup route of PostController
Route::resource('posts', PostController::class); Route::get('/posts/delete/{post}', [PostController::class, 'delete']);
So, following steps above we will be able to create many to many relationship between posts and tags in no time.