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