Factory و Seeder پیشرفته در Laravel — داده تست واقعگرایانه
Factory فقط برای «ساختن ۱۰ تا رکورد random» نیست — ابزار اصلی تست، staging و demo است. وقتی Post::factory()->published()->for($user)->create() را بلد باشید، feature testها سریع و خوانا میشوند. Seeder هم برای محیط local و portfolio-profile این پروژه همان الگو را دنبال میکند.
ساخت Factory
php artisan make:factory PostFactory --model=Post
public function definition(): array
{
return [
'title' => fake()->sentence(4),
'slug' => fake()->unique()->slug(3),
'excerpt' => fake()->paragraph(),
'content' => '<p>'.fake()->paragraphs(3, true).'</p>',
'status' => PostStatus::Draft,
'published_at' => null,
];
}
State — حالتهای از پیش تعریفشده
public function published(): static
{
return $this->state(fn () => [
'status' => PostStatus::Published,
'published_at' => now()->subDays(rand(1, 30)),
]);
}
public function featured(): static
{
return $this->state(['is_featured' => true]);
}
// استفاده
Post::factory()->published()->featured()->count(5)->create();
Relation در Factory
Post::factory()
->for(User::factory())
->for(Category::factory(), 'category')
->has(Tag::factory()->count(3))
->published()
->create();
for() belongsTo؛ has() hasMany/hasOne.
afterCreating — side effect کنترلشده
public function configure(): static
{
return $this->afterCreating(function (Post $post) {
$post->tags()->attach(Tag::factory()->count(2)->create());
});
}
Seeder ترتیبی
class BlogSeeder extends Seeder
{
public function run(): void
{
$user = User::factory()->create(['email' => 'author@test.local']);
$categories = Category::factory()->count(3)->create();
Post::factory()
->count(20)
->published()
->recycle($categories)
->for($user)
->create();
}
}
recycle() از همان collection برای relation استفاده میکند — سریعتر.
withoutModelEvents در seed انبوه
Post::withoutEvents(fn () => Post::factory()->count(1000)->create());
از fire شدن Observer در seed جلوگیری میکند.
Seeder از فایل PHP (الگوی این پروژه)
داده در database/data/blog/posts.php — readable، version control، بدون Faker برای محتوای واقعی. ترکیب هر دو: Factory برای تست، PHP file برای محتوای seed ثابت.
اشتباهات
- seed production با Faker
- فراموش unique روی slug/email
- ساخت ۱۰۰۰ رکورد با Observer سنگین
- hardcode id بهجای factory relation
جمعبندی
Factory = تست سریع. Seeder = محیط قابل تکرار. روابط، db:seed.