وقتی یک پروژه Laravel را توسعه میدهیم، فقط ساخت جداول دیتابیس کافی نیست. در بسیاری از پروژهها لازم است هنگام نصب یا راهاندازی سیستم، تعدادی داده اولیه نیز داخل دیتابیس قرار بگیرد.
برای مثال، یک فروشگاه اینترنتی ممکن است از همان ابتدا به دستهبندیهای مشخصی نیاز داشته باشد:
موبایل
لپتاپ
لوازم جانبی
گیمینگ
شبکه
یا یک پنل مدیریت ممکن است به یک کاربر Administrator نیاز داشته باشد.
و یا یک سیستم آموزشی ممکن است از ابتدا دارای تعدادی وضعیت، نقش کاربری یا تنظیمات پیشفرض باشد.
اگر بخواهیم این دادهها را هر بار به صورت دستی وارد کنیم، مدیریت پروژه سخت و مستعد خطا میشود.
Laravel برای حل این مسئله قابلیتی به نام Seeder در اختیار ما قرار میدهد.
Seeder به ما اجازه میدهد دادههای اولیه یا مورد نیاز پروژه را به صورت کد تعریف کنیم و با یک دستور آنها را وارد دیتابیس کنیم.
در این مقاله از پایه با Seeder در Laravel آشنا میشویم و یاد میگیریم:
- Seeder چیست؟
- چه تفاوتی بین Migration و Seeder وجود دارد؟
- چگونه Seeder بسازیم؟
- DatabaseSeeder چیست؟
- چگونه داده وارد دیتابیس کنیم؟
- چگونه از Model و Eloquent در Seeder استفاده کنیم؟
- چگونه Seeder مشخصی را اجرا کنیم؟
- چگونه Seeder را همراه Migration اجرا کنیم؟
- چگونه دادههای ثابت و اولیه ایجاد کنیم؟
- چگونه از Factory در Seeder استفاده کنیم؟
- چه اشتباهاتی هنگام استفاده از Seeder نباید انجام دهیم؟
Seeder در Laravel چیست؟
Seeder در Laravel ابزاری برای وارد کردن داده به دیتابیس به صورت برنامهریزیشده و قابل تکرار است.
به جای اینکه دادهها را مستقیماً از طریق phpMyAdmin یا نرمافزارهای مدیریت دیتابیس وارد کنیم، میتوانیم آنها را داخل یک کلاس PHP تعریف کنیم.
برای مثال:
DB::table('categories')->insert([
'name' => 'Laravel',
]);
با اجرای Seeder، این اطلاعات وارد دیتابیس میشوند.
بنابراین میتوان گفت:
> Seeder در Laravel برای ایجاد و وارد کردن دادههای اولیه، پیشفرض یا مورد نیاز محیط پروژه استفاده میشود.
# چرا از Seeder استفاده میکنیم؟
فرض کنید یک پروژه فروشگاهی ساختهاید.
برای اجرای صحیح پروژه، به این اطلاعات نیاز دارید:
دستهبندیها
نقشهای کاربری
تنظیمات اولیه
کاربر مدیر
وضعیتهای سفارش
اگر این دادهها را دستی وارد کنید، هر بار که پروژه را روی سیستم جدید نصب میکنید باید دوباره این کارها را انجام دهید.
Seeder این فرآیند را قابل تکرار میکند.
مثلاً:
Project
↓
Migration
↓
Create Tables
↓
Seeder
↓
Insert Initial Data
↓
Application Ready
# تفاوت Migration و Seeder چیست؟
این دو مفهوم معمولاً کنار هم استفاده میشوند، اما وظیفه متفاوتی دارند.
| ابزار | وظیفه |
|---|---|
| Migration | ایجاد و تغییر ساختار دیتابیس |
| Seeder | وارد کردن داده به دیتابیس |
| Factory | تولید دادههای آزمایشی و ساختگی |
| Eloquent | کار کردن با دادههای دیتابیس |
مثلاً:
Migration
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
این کد جدول را ایجاد میکند.
Seeder
DB::table('categories')->insert([
'name' => 'Laravel',
]);
این کد داده داخل جدول قرار میدهد.
بنابراین:
Migration
↓
ساختار
Seeder
↓
داده اولیه
# Seederها کجا قرار دارند؟
Seederهای Laravel در مسیر زیر قرار میگیرند:
database/seeders
ساختار معمول:
database/
└── seeders/
├── DatabaseSeeder.php
└── CategorySeeder.php
فایل اصلی این بخش معمولاً:
DatabaseSeeder.php
است.
# چگونه یک Seeder بسازیم؟
برای ساخت Seeder از Artisan استفاده میکنیم.
مثلاً برای دستهبندیها:
php artisan make:seeder CategorySeeder
Laravel فایل زیر را ایجاد میکند:
database/seeders/CategorySeeder.php
ساختار اولیه فایل تقریباً به این شکل است:
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class CategorySeeder extends Seeder
{
public function run(): void
{
//
}
}
کد اصلی Seeder را داخل متد:
run()
قرار میدهیم.
# اولین Seeder در Laravel
فرض کنیم جدول categories را با Migration ایجاد کردهایم.
حالا میخواهیم سه دستهبندی اولیه ایجاد کنیم.
Seeder:
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class CategorySeeder extends Seeder
{
public function run(): void
{
DB::table('categories')->insert([
[
'name' => 'Laravel',
],
[
'name' => 'PHP',
],
[
'name' => 'WordPress',
],
]);
}
}
در این مثال از Query Builder و DB استفاده کردهایم.
# اجرای Seeder
اگر بخواهیم DatabaseSeeder را اجرا کنیم:
php artisan db:seed
اما برای اینکه CategorySeeder نیز اجرا شود، باید آن را از داخل DatabaseSeeder فراخوانی کنیم.
# DatabaseSeeder چیست؟
فایل:
database/seeders/DatabaseSeeder.php
Seeder اصلی پروژه است.
در این فایل میتوانیم Seederهای مختلف را مدیریت کنیم.
مثلاً:
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run(): void
{
$this->call([
CategorySeeder::class,
]);
}
}
حالا اگر دستور زیر را اجرا کنیم:
php artisan db:seed
Laravel ابتدا DatabaseSeeder را اجرا میکند و سپس CategorySeeder نیز اجرا خواهد شد.
# اجرای چند Seeder
فرض کنید پروژه ما چند Seeder دارد:
UserSeeder
CategorySeeder
ProductSeeder
SettingSeeder
میتوانیم همه آنها را در DatabaseSeeder قرار دهیم:
public function run(): void
{
$this->call([
UserSeeder::class,
CategorySeeder::class,
ProductSeeder::class,
SettingSeeder::class,
]);
}
Laravel آنها را بر اساس ترتیبی که مشخص کردهایم اجرا میکند.
این موضوع زمانی اهمیت پیدا میکند که یک Seeder به داده ایجادشده توسط Seeder دیگری وابسته باشد.
# اجرای یک Seeder مشخص
گاهی نمیخواهیم تمام Seederها اجرا شوند.
مثلاً فقط میخواهیم CategorySeeder اجرا شود.
میتوانیم بنویسیم:
php artisan db:seed --class=CategorySeeder
این روش برای توسعه و تست بسیار کاربردی است.
# استفاده از Model در Seeder
به جای DB::table() میتوانیم از Eloquent Model نیز استفاده کنیم.
فرض کنیم Model زیر را داریم:
class Category extends Model
{
protected $fillable = [
'name',
];
}
حالا Seeder:
use App\Models\Category;
class CategorySeeder extends Seeder
{
public function run(): void
{
Category::create([
'name' => 'Laravel',
]);
Category::create([
'name' => 'PHP',
]);
Category::create([
'name' => 'WordPress',
]);
}
}
این روش زمانی مفید است که بخواهیم از امکانات Eloquent و منطق مرتبط با Model استفاده کنیم.
# DB یا Eloquent؛ کدام را در Seeder استفاده کنیم؟
هر دو روش کاربرد دارند.
استفاده از DB
DB::table('categories')->insert([
'name' => 'Laravel',
]);
مناسب برای:
- دادههای ساده
- Insertهای مستقیم
- Seedهای زیرساختی
- زمانی که نمیخواهیم منطق Model درگیر شود
استفاده از Eloquent
Category::create([
'name' => 'Laravel',
]);
مناسب برای:
- کار با Model
- پروژههایی که منطق داده در Model قرار دارد
- ساخت دادههای مرتبط
- استفاده از امکانات Eloquent
انتخاب روش باید بر اساس نیاز پروژه انجام شود.
# ساخت Seeder برای کاربر مدیر
یکی از کاربردهای رایج Seeder، ساخت یک Administrator اولیه است.
مثلاً:
php artisan make:seeder AdminUserSeeder
سپس:
<?php
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
class AdminUserSeeder extends Seeder
{
public function run(): void
{
User::create([
'name' => 'Administrator',
'email' => 'admin@example.com',
'password' => Hash::make('change-this-password'),
]);
}
}
سپس در:
DatabaseSeeder.php
آن را اضافه میکنیم:
$this->call([
AdminUserSeeder::class,
]);
نکته امنیتی مهم
در پروژه واقعی نباید یک رمز عبور ثابت و قابل حدس را در کد Production قرار دهید.
اگر Seeder برای ساخت حساب اولیه مدیر استفاده میشود، بهتر است فرآیند راهاندازی پروژه امن باشد و اطلاعات حساس از Environment یا فرآیند Setup دریافت شوند.
# استفاده از updateOrCreate در Seeder
یکی از مشکلات Seeder این است که اگر چند بار اجرا شود، ممکن است دادههای تکراری ایجاد کند.
برای برخی دادههای ثابت میتوان از روشهایی مانند updateOrCreate() استفاده کرد.
مثلاً:
User::updateOrCreate(
['email' => 'admin@example.com'],
[
'name' => 'Administrator',
'password' => Hash::make('change-this-password'),
]
);
در این حالت Laravel بر اساس ایمیل، رکورد را پیدا میکند و در صورت وجود آن را بهروزرسانی میکند؛ در غیر این صورت رکورد جدید میسازد.
البته اینکه Seeder باید قابل اجرای مجدد باشد یا نه، به نوع داده و نیاز پروژه بستگی دارد.
# Seeder و دادههای ثابت
یکی از بهترین کاربردهای Seeder، ایجاد دادههایی است که بخشی از منطق اولیه سیستم محسوب میشوند.
مثلاً:
Order Status
Payment Status
User Roles
Categories
Default Settings
Permissions
برای مثال:
DB::table('order_statuses')->insert([
['name' => 'pending'],
['name' => 'paid'],
['name' => 'shipped'],
['name' => 'completed'],
]);
این اطلاعات ممکن است در شروع پروژه لازم باشند.
# Seeder برای Permission و Role
در پروژههایی که سیستم Role و Permission دارند، Seeder میتواند برای ایجاد نقشها و مجوزهای اولیه استفاده شود.
مثلاً منطق کلی:
Seeder
↓
Create Permissions
↓
Create Roles
↓
Assign Permissions
↓
Create Admin
این ساختار در پنلهای مدیریت Laravel بسیار رایج است.
# Seeder و Factory چه تفاوتی دارند؟
Seeder و Factory را نباید با یکدیگر اشتباه گرفت.
Seeder مشخص میکند چه دادهای باید وارد دیتابیس شود.
Factory برای تولید نمونههای دادهای معمولاً آزمایشی و قابل تولید مجدد استفاده میشود.
مثلاً Factory میتواند ۱۰۰۰ کاربر تولید کند:
User::factory()->count(1000)->create();
اما Seeder مشخص میکند چه Seedهایی باید اجرا شوند.
بنابراین میتوان این دو را با هم ترکیب کرد.
# استفاده از Factory داخل Seeder
فرض کنیم یک Factory برای User داریم.
در DatabaseSeeder میتوانیم بنویسیم:
use App\Models\User;
public function run(): void
{
User::factory()->count(50)->create();
}
حالا با:
php artisan db:seed
تعدادی کاربر آزمایشی ایجاد میشود.
این روش برای محیط Development بسیار کاربردی است.
# ترکیب Seeder و Factory
مثلاً برای یک فروشگاه:
public function run(): void
{
User::factory()
->count(20)
->create();
Product::factory()
->count(100)
->create();
}
با اجرای Seeder:
20 Users
100 Products
ایجاد میشوند.
این روش باعث میشود محیط توسعه سریعتر برای تست آماده شود.
# اجرای Migration و Seeder با هم
در پروژههای توسعهای معمولاً میتوان Migration را از ابتدا اجرا کرد و سپس Seeder را نیز اجرا کرد.
یک روش رایج:
php artisan migrate:fresh --seed
این دستور:
- جدولها را از ابتدا ایجاد میکند.
- Migrationها را اجرا میکند.
- Seeder اصلی را اجرا میکند.
مثلاً:
migrate:fresh
↓
Create Tables
↓
--seed
↓
Insert Initial/Test Data
هشدار
این دستور جدولهای موجود را حذف میکند و برای Production مناسب نیست.
# اجرای Seeder در زمان Deploy
در برخی پروژهها هنگام Deploy لازم است دادههای اولیه یا تغییرات دادهای مشخصی اجرا شوند.
اما باید بین Seederهای Development و دادههای حساس Production تفاوت قائل شد.
برای مثال، ساخت ۱۰۰۰ کاربر آزمایشی در Production منطقی نیست.
بنابراین بهتر است Seederها بر اساس هدفشان دستهبندی و کنترل شوند.
# آیا Seeder فقط برای Development است؟
خیر.
Seeder میتواند در Production نیز کاربرد داشته باشد.
مثلاً برای ایجاد:
- تنظیمات اولیه
- وضعیتهای ثابت
- Roleها
- Permissionها
- دادههای پایه سیستم
اما باید با دقت طراحی شود.
Seederهای مربوط به داده آزمایشی معمولاً نباید روی Production اجرا شوند.
# Idempotent بودن Seeder چیست؟
یکی از مفاهیم مهم در Seed کردن داده، امکان اجرای مجدد بدون ایجاد مشکل است.
فرض کنید این Seeder را داریم:
DB::table('categories')->insert([
'name' => 'Laravel',
]);
اگر چند بار اجرا شود ممکن است چند رکورد مشابه ایجاد شود.
اما میتوانیم برای دادههای مشخص از روشهایی مانند:
Category::updateOrCreate(
['name' => 'Laravel'],
[]
);
استفاده کنیم.
در این حالت اجرای چندباره Seeder میتواند قابل کنترلتر باشد.
البته برای همه Seederها یک راهحل واحد وجود ندارد و باید بر اساس نوع داده تصمیم گرفت.
# استفاده از Unique Constraint در کنار Seeder
اگر یک داده نباید تکراری باشد، بهتر است فقط به Seeder اعتماد نکنیم.
مثلاً در Migration:
$table->string('name')->unique();
و در Seeder منطق مناسب برای پیدا کردن یا ایجاد رکورد را داشته باشیم.
این یعنی:
Application Logic
+
Database Constraint
↓
Data Integrity
محدودیتهای دیتابیس یک لایه مهم برای جلوگیری از دادههای نامعتبر هستند.
# ترتیب اجرای Seederها
فرض کنیم:
RoleSeeder
PermissionSeeder
UserSeeder
و UserSeeder به Role نیاز دارد.
در این حالت بهتر است ترتیب اجرای آنها مشخص باشد:
$this->call([
PermissionSeeder::class,
RoleSeeder::class,
UserSeeder::class,
]);
یعنی ابتدا Permissionها، سپس Roleها و در نهایت User ایجاد شوند.
در پروژههای پیچیدهتر، وابستگی بین Seedها باید از ابتدا طراحی شود.
# ساختار پیشنهادی Seeder در پروژههای بزرگ
در پروژههای کوچک ممکن است فقط این فایل کافی باشد:
database/
└── seeders/
└── DatabaseSeeder.php
اما در پروژههای بزرگتر بهتر است Seedها تفکیک شوند:
database/
└── seeders/
├── DatabaseSeeder.php
├── UserSeeder.php
├── RoleSeeder.php
├── PermissionSeeder.php
├── CategorySeeder.php
├── ProductSeeder.php
└── SettingSeeder.php
و DatabaseSeeder نقش هماهنگکننده را داشته باشد.
# مثال کامل یک فروشگاه
فرض کنیم یک فروشگاه Laravel داریم.
میخواهیم دادههای اولیه زیر ایجاد شوند:
Roles
Categories
Admin User
RoleSeeder
class RoleSeeder extends Seeder
{
public function run(): void
{
DB::table('roles')->insert([
['name' => 'admin'],
['name' => 'customer'],
]);
}
}
CategorySeeder
class CategorySeeder extends Seeder
{
public function run(): void
{
DB::table('categories')->insert([
['name' => 'Laravel'],
['name' => 'PHP'],
['name' => 'WordPress'],
]);
}
}
AdminUserSeeder
class AdminUserSeeder extends Seeder
{
public function run(): void
{
User::updateOrCreate(
['email' => 'admin@example.com'],
[
'name' => 'Administrator',
'password' => Hash::make('change-this-password'),
]
);
}
}
DatabaseSeeder
public function run(): void
{
$this->call([
RoleSeeder::class,
CategorySeeder::class,
AdminUserSeeder::class,
]);
}
حالا:
php artisan db:seed
و Seedهای مشخصشده اجرا میشوند.
# دستورات مهم Seeder در Laravel
ساخت Seeder
php artisan make:seeder CategorySeeder
اجرای DatabaseSeeder
php artisan db:seed
اجرای Seeder مشخص
php artisan db:seed --class=CategorySeeder
اجرای Migration و Seeder از ابتدا
php artisan migrate:fresh --seed
این چهار دستور از مهمترین دستورهایی هستند که هنگام کار با Seeder به آنها نیاز خواهید داشت.
# خطاهای رایج هنگام استفاده از Seeder
۱. اجرای Seeder قبل از Migration
اگر جدول وجود نداشته باشد:
DB::table('categories')->insert(...)
با خطا مواجه میشود.
بنابراین ابتدا باید ساختار دیتابیس ایجاد شده باشد.
۲. ایجاد دادههای تکراری
اگر Seeder چند بار اجرا شود و از insert() ساده استفاده کرده باشید، ممکن است دادههای تکراری ایجاد شوند.
برای دادههای خاص میتوان از روشهایی مانند:
updateOrCreate()
استفاده کرد.
۳. وابستگی اشتباه بین Seederها
اگر UserSeeder به Role نیاز داشته باشد، باید Role قبل از User ایجاد شود.
۴. قرار دادن داده آزمایشی در Seeder Production
دادههای تستی را نباید بدون کنترل وارد محیط Production کرد.
۵. قرار دادن اطلاعات حساس در Seeder
اطلاعاتی مانند رمز عبور، Token و Secret نباید به صورت ناامن داخل سورس کد قرار بگیرند.
# بهترین روش استفاده از Seeder
یک ساختار مناسب برای پروژه Laravel میتواند این باشد:
Migration
↓
Create Database Structure
↓
Seeder
↓
Create Required Initial Data
↓
Factory
↓
Create Test Data
به این ترتیب هر ابزار وظیفه مشخصی دارد.
Migration
ساختار را ایجاد میکند.
Seeder
دادههای مورد نیاز سیستم را ایجاد میکند.
Factory
دادههای آزمایشی تولید میکند.
Eloquent
برای کار کردن با دادهها در برنامه استفاده میشود.
# جمعبندی
Seeder یکی از ابزارهای مهم Laravel برای مدیریت دادههای اولیه و قابل تکرار است.
با استفاده از Seeder میتوانیم اطلاعاتی مانند:
- دستهبندیها
- نقشهای کاربری
- Permissionها
- تنظیمات اولیه
- وضعیتهای سیستم
- کاربر اولیه
- دادههای آزمایشی
را به صورت برنامهریزیشده ایجاد کنیم.
مهمترین دستور ساخت Seeder:
php artisan make:seeder CategorySeeder
اجرای Seeder:
php artisan db:seed
اجرای Seeder مشخص:
php artisan db:seed --class=CategorySeeder
و اجرای Migration همراه با Seeder:
php artisan migrate:fresh --seed
است.
نکته مهم این است که Migration، Seeder و Factory سه مفهوم متفاوت هستند و هر کدام وظیفه مشخصی دارند. وقتی این سه ابزار را در کنار Eloquent استفاده کنیم، مدیریت دیتابیس پروژههای Laravel بسیار منظمتر میشود.
# سوالات متداول درباره Seeder در Laravel
Seeder در Laravel چیست؟
Seeder ابزاری برای ایجاد و وارد کردن دادههای اولیه یا مورد نیاز پروژه به دیتابیس است.
چگونه در Laravel Seeder بسازیم؟
با دستور زیر:
php artisan make:seeder CategorySeeder
چگونه Seeder را اجرا کنیم؟
php artisan db:seed
چگونه فقط یک Seeder را اجرا کنیم؟
php artisan db:seed --class=CategorySeeder
تفاوت Seeder و Migration چیست؟
Migration ساختار دیتابیس را ایجاد یا تغییر میدهد، در حالی که Seeder داده داخل دیتابیس ایجاد میکند.
تفاوت Seeder و Factory چیست؟
Seeder مسئول اجرای Seedهای پروژه و ایجاد دادههای مورد نیاز است؛ Factory بیشتر برای تولید دادههای نمونه و آزمایشی استفاده میشود.
آیا Seeder در Production قابل استفاده است؟
بله، اما باید با دقت استفاده شود. Seederهای مربوط به داده آزمایشی نباید بدون کنترل روی Production اجرا شوند.
چگونه Seeder را همراه Migration اجرا کنیم؟
میتوان از:
php artisan migrate:fresh --seed
استفاده کرد؛ البته این دستور برای محیط Development مناسب است، زیرا جدولهای موجود را حذف میکند.
مقاله بعدی در مسیر آموزش Laravel
تا اینجا مسیر به شکل زیر پیش رفته است:
Session
↓
Cookie
↓
Migration
↓
Seeder
↓
Factory
↓
Eloquent
بنابراین مقاله بعدی این Cluster، Factory در Laravel خواهد بود؛ جایی که با تولید دادههای آزمایشی، ساخت Factory، استفاده از Faker و ترکیب Factory با Seeder آشنا میشویم.





