文章转发自专业的 Laravel 开发者社区,原始链接:https://learnku.com/laravel/t…
要点 1. 使用 updateOrCreate() 来避免重复填充
想象一下这个填充代码,想象一下由于一些原因这个填充将被多次启动:
public function run()
{
$items = [['id' => 1, 'title' => 'Administrator'],
['id' => 2, 'title' => 'Simple user'],
];
foreach ($items as $item) {Role::create($item);
}
}
第二次尝试执行填充的时候可能会因为 ID 冲突而失败。在其他情况下,如果你没有指定 ID,然后你可能会在表中填充很多数据,并且是重复输入。为了避免此情况,可以尝试以下方式:
foreach ($items as $item) {Role::updateOrCreate(['id' => $item['id']], $item);
}
要点 2. 只运行一个 Seeder 类
前段时间我十分惊讶多少人不知道在执行 php artisan db:seed 命令时可以指定一个填充类。
php artisan db:seed
这个命令会启动在 DatabaseSeeder.php 文件中列出的所有类。
但你可以将启动限制在一个精确的填充类中:
php artisan db:seed --class=UsersTableSeeder
要点 3. 从迁移文件中执行 Seeder 类
通常你需要创建一个新的数据表,并且马上需要填充一些数据。但在生成环节中你不能马上执行 “artisan db:seed”,尤其如果你有仅涉及到 “artisan migrate” 命令的自动部署程序。
小手段是从迁移文件中启动特定的填充文件。
public function up()
{Schema::create('themes', function (Blueprint $table) {$table->increments('id');
$table->text('name');
});
Artisan::call('db:seed', ['--class' => ThemesTableSeeder::class]);
}
要点 4. 有关联的 Seeder 工厂类: 使用父级工厂类
如果你正在构建工厂类来做你的数据填充,你是如何处理两个模型之间的关系的呢?例如,你需要填充 10 个公司和这些公司的 10 个联系方式?
你的 database/factories/CompanyFactory.php 大概会是这样:
$factory->define(App\Contact::class, function (Faker\Generator $faker) {
return ['company_id' => factory('App\Company')->create()->id,
'first_name' => $faker->firstName(),
'last_name' => $faker->lastName,
'phone1' => $faker->phoneNumber,
'phone2' => $faker->phoneNumber,
'email' => $faker->email,
'skype' => $faker->word,
'address' => $faker->address,
];
});
有没有发现它是如何填充 company_id 的嘛?直接使用另一个工厂。
要点 5. DatabaseSeeder 应对本地和生产环境
有时候你仅在本地环境下需要填充某些数据,生产环境下则并不需要。或者,使用不同的填充文件来填充不同的环境。
我不是很确定这是否是最优雅的处理方式,但这是过去我如何整理本地和生产环境下不同填充类的方法。
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{if (app()->environment() == 'production') {$this->call(ThemesTableSeeder::class);
$this->call(LanguagesTableSeeder::class);
} else {$this->call(UsersTableSeeder::class);
$this->call(ModulesTableSeeder::class);
$this->call(ThemesTableSeeder::class);
$this->call(LanguagesTableSeeder::class);
}
}
}
要点 6. 使用 iSeed 生成基于 Database 的填充类
最后一个要点可以说是一个我自己使用过不少时间的工具,叫 iSeed Generator。
安装完成后,你可以运行下面的命令:
$ php artisan iseed users --force
这会在你的 seeds
目录下生成 UsersTableSeeder.php
文件,--force
选项是用来强制覆盖任何已经存在的填充类。
要点 7. 在生产环境中运行数据填充
要点都在这儿了,最后说一个在构建填充类时的小常识,在你的 local/staging 本地环境中你可以反复运行 “artisan migrate:fresh –seed” 无任何风险,这不会丢失任何重要的数据,但在 production 生产环境中你只能运行 “artisan db:seed” 一次 ,然后彻底忘掉这个操作。如果你要在生产环境填充额外的数据,那就把它放到迁移文件中,详见要点 3。