laravel進階--3 數據庫填充器及模型工廠

生成填充器

要生成一個填充器,可以通過 Artisan 命令 make:seeder。所有框架生成的填充器都位於 database/seeds 目錄:

php artisan make:seeder StudentsTableSeeder

編輯填充器

<?php

use Illuminate\Database\Seeder;
use App\Http\Models\Student;
class StudentsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //
        //手動填充
        // DB::table('students')->insert([
        //     'name'=>str_random(10),
        //     'age'=>rand(10,30),
        //     'sex'=>rand(10,30),
        // ]);
        
        //模型工廠批量填充

        //make() 生成假數據
       // $student = factory(App\Http\Models\Student::class)->make();
        //$student = factory(Student::class,5)->make();

        //create() 生成假數據並填充到數據庫
        $student = factory(Student::class,5)->create();

        //var_dump($student);exit();

    }
}

調用其他填充器

 

在 DatabaseSeeder 類中,你可以使用 call 方法執行其他填充類,使用 call 方法允許你將數據庫填充分解成多個文件,這樣單個填充器類就不會變得無比巨大,只需簡單將你想要運行的填充器類名傳遞過去即可:

/**
 * 運行數據庫填充
 *
 * @return void
 */
public function run(){
    $this->call(UsersTableSeeder::class);
    $this->call(PostsTableSeeder::class);
    $this->call(CommentsTableSeeder::class);
}

運行填充器

編寫好填充器類之後,需要通過 dump-autoload 命令重新生成 Composer 的自動加載器:

composer dump-autoload

運行之後可以使用 Artisan 命令 db:seed 來填充數據庫。默認情況下,db:seed 命令運行 DatabaseSeeder 類,不過,你也可以使用 --class 選項來指定你想要運行的獨立的填充器類:

//運行所有填充器
php artisan db:seed
//運行指定填充器
php artisan db:seed --class=StudentsTableSeeder

運行之後可能報錯,是因爲Student模型類沒有設置

<?php

namespace App\Http\Models;

use Illuminate\Database\Eloquent\Model;

class Student extends Model
{
    //
    /**
     * 關聯到模型的數據表
     *
     * @var string
     */
    protected $table = 'students';

    /**
     * 定義主鍵
     *
     * @var string
     */
    protected $primaryKey = 'id';

    /**
     * 模型日期列的存儲格式
     * $dateFormat 屬性。該屬性決定日期被如何存儲到數據庫中,以及模型被序列化爲數組或 JSON 時日期的格式
     * $dateFormat 可以接受的值和 php 中 date () 函數第一個參數可以接受的值一樣。
     *  U 的意思就是我們平常說的時間戳 (10 位到秒)
     * Y m d H i s 都可用
     * @var string
     */
   protected $dateFormat = 'U';

    /**
     * 不能被批量賦值的屬性
     * 黑名單
     * @var array
     */
   // protected $guarded = ['price'];
   protected $guarded = [];//所有屬性都可賦值
}

模型工廠

生成模型工廠

模型工廠可用於快速填充數據表。要創建一個模型工廠,可以使用 Artisan 命令 make:factory:

php artisan make:factory StudentFactory

新創建的工廠類位於 database/factories 目錄下。

--model 選項可用於指示模型工廠對應的模型類。該選項通過給定的模型名稱預填充生成的工廠類:

php artisan make:factory StudentFactory --model=Student

編輯模型工廠

PHP 庫 Faker : https://github.com/fzaninotto/Faker

在閉包中,作爲工廠定義,我們返回該模型上所有屬性默認測試值。該閉包接收 PHP 庫 Faker 實例,從而允許你方便地爲測試生成多種類型的隨機數據

<?php

use Faker\Generator as Faker;
use App\Http\Models\Student;
$factory->define(Student::class, function (Faker $faker) {
    return [
        //
        'name' => $faker->word(),
        'age' => $faker->numberBetween(10,50),
        'sex' => $faker->randomElement(array(10,20,30)),
        'created_at' => $faker->unixTime(),
        'updated_at' => $faker->unixTime(),
    ];
});

使用工廠

創建模型

 

定義好工廠後,可以在測試或數據庫填充文件中通過全局的 factory 方法使用它們來生成模型實例,所以,讓我們看一些創建模型的例子,首先,我們使用 make 方法,該方法創建模型但不將其保存到數據庫:

public function testDatabase(){
    $user = factory(App\User::class)->make();
    // 用戶模型測試...
}

//還可以創建多個模型集合或者創建給定類型的模型:

// 創建3個 App\User 實例...
$users = factory(App\User::class, 3)->make();

 

應用狀態

還可以應用任意狀態到模型,如果你想要應用多個狀態轉化到模型,需要指定每個你想要應用的狀態名:

$users = factory(App\User::class, 5)->states('deliquent')->make();
$users = factory(App\User::class, 5)->states('premium', 'deliquent')->make();

覆蓋屬性

如果你想要覆蓋模型中的某些默認值,可以傳遞數組值到 make 方法,只有指定值纔會被替換,剩下值保持工廠指定的默認值不變:

$user = factory(App\User::class)->make([
    'name' => 'Abigail',
]);

持久化模型

create 方法不僅能創建模型實例,還可以使用 Eloquent 的 save 方法將它們保存到數據庫

public function testDatabase()
{
    // 創建單個 App\User 實例...
    $user = factory(App\User::class)->create();

    // 創建3個 App\User 實例...
    $users = factory(App\User::class, 3)->create();

    // 在測試中使用模型...
}

你可以通過傳遞數組到 create 方法覆蓋模型上的屬性:
$user = factory(App\User::class)->create([
    'name' => 'Abigail',
]);

關聯關係

 

在本例中,我們添加一個關聯到創建的模型,使用 create 方法創建多個模型的時候,會返回一個 Eloquent 集合實例,從而允許你使用集合提供的所有方法,例如 each:

$users = factory(App\User::class, 3)
           ->create()
           ->each(function($u) {
                $u->posts()->save(factory(App\Post::class)->make());
            });

關聯關係 & 屬性閉包

 

還可以使用工廠中的閉包屬性添加關聯關係到模型,例如,如果你想要在創建 Post 的時候創建一個新的 User 實例,可以這麼做:

$factory->define(App\Post::class, function ($faker) {
    return [
        'title' => $faker->title,
        'content' => $faker->paragraph,
        'user_id' => function () {
            return factory(App\User::class)->create()->id;
        }
    ];
});

這些閉包還接收包含它們的工廠屬性數組:

$factory->define(App\Post::class, function ($faker) {
    return [
        'title' => $faker->title,
        'content' => $faker->paragraph,
        'user_id' => function () {
            return factory(App\User::class)->create()->id;
        },
        'user_type' => function (array $post) {
            return App\User::find($post['user_id'])->type;
        }
    ];
});

 

 

 

發佈了76 篇原創文章 · 獲贊 5 · 訪問量 9219
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章