如果外部 ID 作为属性传递,则防止在工厂中创建关系模型
Prevent creating relation model in factory if foreign id passed as attribute
让我们假设这个工厂:
PostFactory.php
$factory->define(Post::class, function (Faker $faker) {
return [
'title'=>$faker->word,
'user_id'=>factory(User::class)->create()->id
];
});
然后我这样使用它:
$user = factory(User::class)->create();
factory(Post::class, 5)->create(['user_id'=>$user->id]);
我预计将创建 1 个用户和 5 个帖子。但实际上数据库中有 6 个用户,因为 PostFactory
创建用户,无论 user_id
是否通过。
如果 user_id
属性传递给 create
方法,有没有办法阻止创建新用户?
有一个解决方法。
$factory->define(Post::class, function (Faker $faker) {
return [
'title'=>$faker->word,
'user_id'=> function () { return factory(User::class)->create()->id; }
];
});
Laravel 在合并属性时调用 value()
助手。如果user_id
存在于属性中则不执行回调,否则执行
您可以在文档中看到它 here 与您的模型完全相同。
对于Laravel 5.1,您需要传递参数并手动检查是否传递了id。
这里是关于这个问题的讨论。
https://github.com/laravel/framework/issues/9245
$factory->define(App\User::class, function ($faker, $attributes) {
$accountId = isset($attributes['account_id']) ? $attributes['account_id']: factory(App\Account::class)->create()->id;
return [
'account_id' => $accountId,
'email' => $faker->email,
'password' => 'secret',
'name' => $faker->name
];
});
让我们假设这个工厂:
PostFactory.php
$factory->define(Post::class, function (Faker $faker) {
return [
'title'=>$faker->word,
'user_id'=>factory(User::class)->create()->id
];
});
然后我这样使用它:
$user = factory(User::class)->create();
factory(Post::class, 5)->create(['user_id'=>$user->id]);
我预计将创建 1 个用户和 5 个帖子。但实际上数据库中有 6 个用户,因为 PostFactory
创建用户,无论 user_id
是否通过。
如果 user_id
属性传递给 create
方法,有没有办法阻止创建新用户?
有一个解决方法。
$factory->define(Post::class, function (Faker $faker) {
return [
'title'=>$faker->word,
'user_id'=> function () { return factory(User::class)->create()->id; }
];
});
Laravel 在合并属性时调用 value()
助手。如果user_id
存在于属性中则不执行回调,否则执行
您可以在文档中看到它 here 与您的模型完全相同。
对于Laravel 5.1,您需要传递参数并手动检查是否传递了id。
这里是关于这个问题的讨论。 https://github.com/laravel/framework/issues/9245
$factory->define(App\User::class, function ($faker, $attributes) {
$accountId = isset($attributes['account_id']) ? $attributes['account_id']: factory(App\Account::class)->create()->id;
return [
'account_id' => $accountId,
'email' => $faker->email,
'password' => 'secret',
'name' => $faker->name
];
});