Suppose there are three tables communities, topics, posts and one pivot table community_topic ( in singular ).
Hence if we want to draw relationship of many to many between communities and topics that is one commnunity can have many topics and on the other hand one topic also can relate to many communities, we need to follow given snippets below step by step to implement it.
Step 01: create fresh laravel project
composer create-project laravel/laravel communityBlog
Step 02: Setting Up scaffolding migration, factory, seeder of Community, Post and Topic model with artisan command
php artisan make:model Community -mfs php artisan make:model Post -mfs php artisan make:model Topic -ms
Step 03: Setting up scaffolding migration of pivot table community_topic
php artisan make:migration create_community_topic_table
Step 04: Setting up database and updating db config in .env file
DB_DATABASE=laravel_seeding_pivot_table
Step 05: Specifying migration definition in database\migrations\2022_09_22_203833_create_communities_table.php
public function up() { Schema::create('communities', function (Blueprint $table) { $table->id(); $table->string('name'); $table->text('description'); $table->timestamps(); }); }
Step 06: Specifying migration definition in database\migrations\2022_09_22_203904_create_topics_table.php
public function up() { Schema::create('topics', function (Blueprint $table) { $table->id(); $table->string('name'); $table->timestamps(); }); }
Step 07: Specifying migration definition in database\migrations\2022_09_22_203917_create_posts_table.php
public function up() { Schema::create('posts', function (Blueprint $table) { $table->id(); $table->foreignId('community_id')->constrained(); $table->foreignId('topic_id')->constrained(); $table->string('title'); $table->text('post_text')->nullable(); $table->timestamps(); $table->softDeletes(); }); }
Step 08: Specifying migration definition in database\migrations\2022_09_22_204130_create_community_topic_table.php
public function up() { Schema::create('community_topic', function (Blueprint $table) { $table->foreignId('community_id')->constrained(); $table->foreignId('topic_id')->constrained(); }); }
Step 09: Setting up Community model in App\Models\Community.php
class Community extends Model { use HasFactory; protected $fillable = [ 'name', 'description']; public function topics() { return $this->belongsToMany(Topic::class); } public function posts() { return $this->hasMany(Post::class); } }
Step 10: Setting up Post model in App\Models\Post.php
class Post extends Model { use HasFactory; protected $fillable = [ 'community_id', 'topic_id', 'title', 'post_text']; public function community() { return $this->belongsTo(Community::class); } public function topic() { return $this->belongsTo(Topic::class); } }
Step 11: Setting up Topic model in App\Models\Topic.php
class Topic extends Model { use HasFactory; protected $fillable = ['name', 'description']; public function posts() { return $this->hasMany(Post::class); } public function community() { return $this->belongsToMany(Community::class); } }
Step 12: Specifying column rules for Community model in CommunityFactory.php
public function definition() { //$name = fake()->name(); return [ 'name' => $this->faker->text(200), 'description' => $this->faker->text(500), ]; }
Step 13: Specifying column rules for Post model in PostFactory.php
use App\Models\Community; use App\Models\Topic; public function definition() { $communityIds = Community::pluck('id'); $topicIds = Topic::pluck('id'); return [ 'community_id' => $communityIds->random(), 'topic_id' => $topicIds->random(), 'title' => $this->faker->text(50), 'post_text' => $this->faker->text(500), ]; }
Step 14: Specifying definition of CommunitySeeder.php
use App\Models\Community; use App\Models\Topic; public function run() { // Community::factory(100)->create(); $communities = Community::all(); $topics = Topic::pluck('id'); foreach( $communities as $community ) { // attaching ( with attach method ) fetched random topic ( topicId only ) // to each of the newly created community // with configured topics() relation $community->topics()->attach($topics->random()); } }
Step 15: Specifying definition of PostSeeder.php
public function run() { Post::factory()->times(200)->create(); }
Step 16: Specifying definition of TopicSeeder.php
public function run() { Topic::create(['name' => 'America']); Topic::create(['name' => 'Asia']); Topic::create(['name' => 'Africa']); Topic::create(['name' => 'Australia']); Topic::create(['name' => 'Europe']); }
Step 17: Running TopicSeeder, CommunitySeeder and PostSeeder using run() method in DatabaseSeeder.php, to run seed data for communities, topics, posts and community_topic table.
public function run() { $this->call(TopicSeeder::class); $this->call(CommunitySeeder::class); $this->call(PostSeeder::class); }
Relations in these seeding and factories are mentioned below.
1. community hasMany topics
2. topics hasMany communities
3. post belongsTo community and topic
4. community hasMany posts
5. topic hasMany posts
Step 18: Finally running following artisan command to run migration and seeding database tables.
php artisan migrate:fresh --seed
Execution of above command, in communities table there will be 100 communities created and in Posts table there will be 200 posts with randomly assigned community and topic. There will be only five rows of data in topics table.
Lastly, pivot table community_topic will hold 100 rows of community data with randomly assigned topic.