Eloquent Many to Many Polymorphic Tutorial in Laravel 11

 <?php


namespace App\Http\Controllers;

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

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        // $post = Post::find(1);
        // return $post->tags;

        // $post = Post::with("tags")->find(1);
        // return $post;

        // $post = Post::with("tags")->get();
        // return $post;

        $posts = Post::with("tags")->get();
        foreach ($posts as $data) {
            echo "<h2>$data->title</h2>";
            echo "<p>$data->description</p>";

            foreach ($data->tags as $dataTwo) {
                echo "$dataTwo->tag_name / ";
            }
        }
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        // $post = Post::create([
        //     "title" => "News Title Four",
        //     "description" => "vel illum qui dolorem eum fugiat quo voluptas nulla pariatur"
        // ]);

        // $post->tags()->create([
        //     "tag_name" => "Sachin Tendulkar"
        // ]);


        // $post = Post::create([
        //     "title" => "News Title Five",
        //     "description" => "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam"
        // ]);

        // $post->tags()->attach(5);

        // attach() method is for assigning and detach() method is for deleting
        // Attach absent post to any tag
        // Here below, post number 3 will assign to tag number(of "tags" table) 2 and 6
        // $post = Post::find(3);
        // $post->tags()->attach([2,6]);

        // Here below, post number 1 will assign to tag number(of "tags" table) 1,3,4
        // $post = Post::find(1);
        // $post->tags()->attach([1,3,4]);

        // Here below, post number 2 will assign to tag number(of "tags" table) 1,5
        // $post = Post::find(2);
        // $post->tags()->attach([1,5]);

        // Here below, post number 5 will assign to tag number(of "tags" table) 8
        // $post = Post::find(5);
        // $post->tags()->attach(8);

        // Here below, post number 3 which assigned to tag number(of "tags" table) 2,6 will removed
        // $post = Post::find(3);
        // $post->tags()->detach([2,6]);

        // Here below, post number 4 will assing to tag number(of "tags" table) 1,2,3,4,5,6,7
        $post = Post::find(4);
        $post->tags()->attach([1, 2, 3, 4, 5, 6, 7]);
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     */
    public function show(string $id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(string $id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id)
    {
        //
    }
}
Above File is app\Http\Controllers\PostController File




Below File is app\Http\Controllers\TagController File
<?php

namespace App\Http\Controllers;

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

class TagController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        // $tag = Tag::with("posts")->find(1);
        // return $tag;

        // $tag = Tag::with("posts")->with("videos")->find(1);  //First way
        // $tag = Tag::with(["posts","videos"])->find(1);      //Second way
        // return $tag;

        // if we want to show title and description as shown below :
        // $tag = Tag::with(["posts:title,description","videos"])->find(1);
        // return $tag;

        // Show data in HTML format as shown below :
        $tag = Tag::with(["posts:title,description", "videos"])->find(1);

        echo "<h2>All Posts:</h2>";
        foreach ($tag->posts as $data) {
            echo "<h2>$data->title</h2>";
            echo "<p>$data->description</p>";
            echo "<hr>";
        }

        echo "<h2>All Videos:</h2>";
        foreach ($tag->videos as $dataTwo) {
            echo "<h2>$dataTwo->title</h2>";
            echo "<p>$dataTwo->url</p>";
            echo "<hr>";
        }
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     */
    public function show(string $id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(string $id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id)
    {
        //
    }
}





Below File is app\Http\Controllers\TaggableController File
<?php

namespace App\Http\Controllers;

use App\Models\Taggable;
use Illuminate\Http\Request;

class TaggableController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     */
    public function show(string $id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(string $id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id)
    {
        //
    }
}





Below File is app\Http\Controllers\VideoController File
<?php

namespace App\Http\Controllers;

use App\Models\Video;
use Illuminate\Http\Request;

class VideoController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        // attach() method is for assigning and detach() method is for deleting
        // Here below, post number 1 will assign to tag number(of "tags" table) 1,4
        // $video = Video::find(1);
        // $video->tags()->attach([1,4]);

        // Here below, post number 1 will assign to tag number(of "tags" table) 2,3,5,6,7,8
        // $video = Video::find(1);
        // $video->tags()->attach([2,3,5,6,7,8]);

        // Here below, post number 2 will assign to tag number(of "tags" table) 1,2,3,4,5,6,7,8
        // $video = Video::find(2);
        // $video->tags()->attach([1,2,3,4,5,6,7,8]);

        $video = Video::find(3);
        $video->tags()->sync([1, 4]);
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     */
    public function show(string $id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(string $id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id)
    {
        //
    }
}





Below File is app\Models\Post File
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    public $timestamps = false;
    protected $table = "posts";
    protected $fillable = ["title", "description"];

    public function tags()
    {
        return $this->morphToMany(Tag::class, "taggable");
    }
}




Below File is app\Models\Tag File
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Tag extends Model
{
    public $timestamps = false;
    protected $table = "tags";
    protected $fillable = ["tag_name"];

    public function posts()
    {
        return $this->morphedByMany(Post::class, "taggable");
    }

    public function videos()
    {
        return $this->morphedByMany(Video::class, "taggable");
    }
}





Below File is app\Models\Taggable File
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Taggable extends Model
{
    public $timestamps = false;
    protected $table = "taggables";
    protected $fillable = ["tag_id", "taggable_id", "taggable_type"];
}





Below File is app\Models\Video File
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Video extends Model
{
    public $timestamps = false;
    protected $table = "videos";
    protected $fillable = ["title", "url"];

    public function tags()
    {
        return $this->morphToMany(Tag::class, "taggable");
    }
}





Below File is database\json\posts File
[
    {
        "title": "News Title One",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
    },
    {
        "title": "News Title Two",
        "description": "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua"
    },
    {
        "title": "News Title Three",
        "description": "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat"
    }
]




Below File is database\json\tags File
[
    {
        "tag_name": "Bollywood"
    },
    {
        "tag_name": "Hollywood"
    },
    {
        "tag_name": "Salman Khan"
    },
    {
        "tag_name": "Shahid Kapoor"
    },
    {
        "tag_name": "Deepika"
    },
    {
        "tag_name": "Tom Hank"
    },
    {
        "tag_name": "Arnold"
    }
]




Below File is database\json\videos File
[
    {
        "title": "Video Title One",
        "url": "videos/first.mp4"
    },
    {
        "title": "Video Title Two",
        "url": "videos/second.mp4"
    },
    {
        "title": "Video Title Three",
        "url": "videos/third.mp4"
    }
]





Below File is database\migrations\2024_12_17_051032_create_videos_table File
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('videos', function (Blueprint $table) {
            $table->id();
            $table->string("title");
            $table->string("url");
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('videos');
    }
};





Below File is database\migrations\2024_12_17_051807_create_posts_table File
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string("title");
            $table->longText("description");
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};





Below File is database\migrations\2024_12_17_052423_create_tags_table File
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('tags', function (Blueprint $table) {
            $table->id();
            $table->string("tag_name");
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('tags');
    }
};





Below File is database\migrations\2024_12_17_054948_create_taggables_table File
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('taggables', function (Blueprint $table) {
            $table->unsignedBigInteger("tag_id");
            $table->unsignedBigInteger("taggable_id");
            $table->string("taggable_type");
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('taggables');
    }
};





Below File is database\seeders\DatabaseSeeder File
<?php

namespace Database\Seeders;

use App\Models\User;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
        // User::factory(10)->create();

        // User::factory()->create([
        //     'name' => 'Test User',
        //     'email' => 'test@example.com',
        // ]);

        $this->call([
            VideoSeeder::class,
            PostSeeder::class,
            TagSeeder::class
        ]);
    }
}





Below File is database\seeders\PostSeeder File
<?php

namespace Database\Seeders;

use App\Models\Post;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\File;

class PostSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        $json = File::get(path: "database/json/posts.json");
        $posts = collect(json_decode($json));

        $posts->each(function ($post) {
            Post::create([
                "title" => $post->title,
                "description" => $post->description
            ]);
        });
    }
}





Below File is database\seeders\TagSeeder File
<?php

namespace Database\Seeders;

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

class TagSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        $json = File::get(path: "database/json/tags.json");
        $tags = collect(json_decode($json));

        $tags->each(function ($tag) {
            Tag::create([
                "tag_name" => $tag->tag_name
            ]);
        });
    }
}





Below File is database\seeders\VideoSeeder File
<?php

namespace Database\Seeders;

use App\Models\Video;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\File;

class VideoSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        $json = File::get(path: "database/json/videos.json");
        $videos = collect(json_decode($json));

        $videos->each(function ($video) {
            Video::create([
                "title" => $video->title,
                "url" => $video->url
            ]);
        });
    }
}





Below File is routes\web File
<?php

use App\Http\Controllers\PostController;
use App\Http\Controllers\TagController;
use App\Http\Controllers\VideoController;
use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});

Route::resource("post", PostController::class);

Route::resource("video", VideoController::class);

Route::resource("tag", TagController::class);









Comments

Popular posts from this blog

Eloquent Many to Many Relationship Tutorial in Laravel 11

Blade Template Tutorial Three Template Inheritance in Laravel 11