> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# 資料庫 Seeding

> 說明如何使用 Laravel 的 seeding 功能將開發／測試用範例資料寫入資料庫。

## 什麼是 Seeding

Seeding 是將範例資料或初始資料寫入資料庫的機制。

在開發環境設定或自動化測試中，通常需要事先有資料。若每次都手動輸入太耗時，用 seeder 將它整理為可反覆執行的形式。

Seeder 類別放在 `database/seeders` 目錄。預設會有 `DatabaseSeeder` 類別。

```mermaid theme={null}
flowchart TD
    A["php artisan db:seed"] --> B["DatabaseSeeder::run()"]
    B --> C["UserSeeder::run()"]
    B --> D["PostSeeder::run()"]
    C --> E["寫入 users 資料表"]
    D --> F["寫入 posts 資料表"]
```

## 建立 Seeder

用 `make:seeder` Artisan 指令產生新的 seeder 類別。

```shell theme={null}
php artisan make:seeder UserSeeder
```

產生的檔案會放在 `database/seeders/UserSeeder.php`。

```php theme={null}
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class UserSeeder extends Seeder
{
    /**
     * 執行 seeder
     */
    public function run(): void
    {
        // 在此撰寫寫入資料的處理
    }
}
```

## Seeder 的實作

在 `run()` 方法中撰寫寫入資料的處理。可用 DB facade 或 Eloquent model 插入。

### 使用 DB facade

```php theme={null}
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;

class UserSeeder extends Seeder
{
    public function run(): void
    {
        DB::table('users')->insert([
            [
                'name' => '山田太郎',
                'email' => 'taro@example.com',
                'password' => Hash::make('password'),
                'created_at' => now(),
                'updated_at' => now(),
            ],
            [
                'name' => '鈴木花子',
                'email' => 'hanako@example.com',
                'password' => Hash::make('password'),
                'created_at' => now(),
                'updated_at' => now(),
            ],
        ]);
    }
}
```

### 使用 Eloquent model

```php theme={null}
use App\Models\User;
use Illuminate\Support\Facades\Hash;

public function run(): void
{
    User::create([
        'name' => '管理者',
        'email' => 'admin@example.com',
        'password' => Hash::make('password'),
    ]);
}
```

<Info>
  執行 seeding 過程中，mass assignment 保護會自動停用。可不用管 `$fillable` 或 `$guarded` 的設定就寫入資料。
</Info>

## 與 Model Factory 的組合

若需要大量測試資料，與 [model factory](/zh-TW/eloquent) 組合會很方便。使用 factory 可一次產生大量隨機假資料。

```php theme={null}
use App\Models\User;
use App\Models\Post;

public function run(): void
{
    // 建立 10 位使用者
    User::factory(10)->create();

    // 為每位使用者建立 3 篇文章
    User::factory(5)
        ->hasPosts(3)
        ->create();
}
```

<Tip>
  Factory 的詳細用法請參閱 Eloquent factory 的文件。
</Tip>

## DatabaseSeeder 的用法

`DatabaseSeeder` 是統一管理多個 seeder 的進入點。用 `call()` 方法指定要執行的 seeder。

```php theme={null}
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    public function run(): void
    {
        $this->call([
            UserSeeder::class,
            PostSeeder::class,
            CommentSeeder::class,
        ]);
    }
}
```

Seeder 會依 `call()` 傳入的順序執行。若有外鍵約束，請安排先 seed 被參考的資料表（如 `users` → `posts`）。

## 執行 Seeder

### 執行全部 seeder

```shell theme={null}
php artisan db:seed
```

會呼叫 `DatabaseSeeder`，並依序執行以 `call()` 指定的 seeder。

### 只執行特定 seeder

用 `--class` 選項指定要執行的 seeder 類別。

```shell theme={null}
php artisan db:seed --class=UserSeeder
```

## 與 Migration 同時執行

若在 `migrate:fresh` 指令加上 `--seed` 選項，會重建所有資料表後一併執行 seeding。

```shell theme={null}
php artisan migrate:fresh --seed
```

若只想執行特定 seeder，使用 `--seeder` 選項。

```shell theme={null}
php artisan migrate:fresh --seed --seeder=UserSeeder
```

<Warning>
  `migrate:fresh` 會刪除並重新建立所有資料表。既有資料全部會遺失，請勿在正式環境使用。
</Warning>

## 在正式環境執行

在正式環境嘗試執行 seeding 時會顯示確認提示。若要不確認直接執行，使用 `--force` 旗標。

```shell theme={null}
php artisan db:seed --force
```

<Warning>
  在正式環境做 seeding 可能造成資料被覆寫或遺失。執行前務必先做備份。
</Warning>

## 抑制 Model 事件

若想避免 seeding 中觸發 model 事件（如 `creating`、`created`），使用 `WithoutModelEvents` trait。

```php theme={null}
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;

class DatabaseSeeder extends Seeder
{
    use WithoutModelEvents;

    public function run(): void
    {
        $this->call([
            UserSeeder::class,
        ]);
    }
}
```

也會套用到經由 `call()` 執行的子 seeder。

## 實務範例：部落格應用的 seeder

以下是設定使用者與文章的部落格應用初始資料的範例。

```php theme={null}
// database/seeders/UserSeeder.php
class UserSeeder extends Seeder
{
    public function run(): void
    {
        User::factory(10)->create();
    }
}

// database/seeders/PostSeeder.php
class PostSeeder extends Seeder
{
    public function run(): void
    {
        // 為每位使用者建立 2〜5 篇文章
        User::all()->each(function ($user) {
            Post::factory(rand(2, 5))->create([
                'user_id' => $user->id,
            ]);
        });
    }
}

// database/seeders/DatabaseSeeder.php
class DatabaseSeeder extends Seeder
{
    public function run(): void
    {
        $this->call([
            UserSeeder::class,
            PostSeeder::class, // 在 users 之後執行
        ]);
    }
}
```

執行步驟：

```shell theme={null}
php artisan migrate:fresh --seed
```

## 後續步驟

<Card title="Eloquent 入門" icon="database" href="/zh-TW/eloquent">
  學習用 Eloquent ORM 取得並操作 seeder 寫入的資料。
</Card>


## Related topics

- [資料庫設定](/zh-TW/database.md)
- [資料庫遷移（Migrations）](/zh-TW/migrations.md)
- [資料庫測試](/zh-TW/database-testing.md)
- [搜尋](/zh-TW/search.md)
- [Laravel Scout](/zh-TW/scout.md)
