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 FileBelow 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);
.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)
Comments
Post a Comment