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

Eloquent with JSON Data Columns Tutorial in Laravel 11

Blade Template Tutorial Three Template Inheritance in Laravel 11