I'm working on a simple blog example. The following code is what I'm currently using to seed posts with tags which appears to work. I'm looking for confirmation on this is the most efficient way. Is there a way to attach the tags as each posts is created and saved?
Posts Table
Schema::create('tags', static function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug')->nullable();
$table->text('description')->nullable();
$table->softDeletes();
$table->timestamps();
});
Tags Table
Schema::create('tags', static function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug')->nullable();
$table->text('description')->nullable();
$table->softDeletes();
$table->timestamps();
});
Post_Tag Table
Schema::create('post_tag', function (Blueprint $table) {
$table->id();
$table->foreignId('post_id')->constrained();
$table->foreignId('tag_id')->constrained();
$table->timestamps();
});
PostFactory
public function definition()
{
$title = rtrim($this->faker->sentence(random_int(5,10)), '.');
$slug = Str::slug($title);
$content = collect($this->faker->paragraphs(random_int(3, 7), true))
->map(static function ($item) {
return $item;
})->toArray();
$content = implode($content);
return [
'title' => $title,
'slug' => $slug,
'content' => $content,
'is_published' => (boolean) random_int(0,1),
];
}
TagFactory
public function definition()
{
$name = $this->faker->word;
$slug = Str::slug($name);
return [
'name' => $name,
'slug' => $slug
];
}
DatabaseSeeder.php
\App\Models\Category::factory(10)->create();
\App\Models\Tag::factory(10)->create();
User::factory(3)->create()->each(static function (User $user) {
$category = Category::all()->random(1)->first();
$user->posts()
->saveMany(Post::factory(random_int(1, 5))->make([
'category_id' => $category->id,
'user_id' => $user->id,
]));
});
$users = User::with('posts')->get();
foreach($users as $user) {
foreach($user->posts as $post) {
$tags = Tag::pluck('id','name')->random(random_int(1,5))->toArray();
$post->tags()->attach($tags);
}
}