生成填充器
要生成一個填充器,可以通過 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;
}
];
});