英文:
Laravel model factory make() bypass create() in foreign key object creation
问题
我有一个用于Customer类的工厂
$factory->define(Customer::class, function (Faker $faker) {
return [
'hotel_id' => function() {
return factory(\App\Hotel::class)->create()->id;
},
'name' => $faker->name,
'phone' => $faker->phoneNumber,
'email' => $faker->email,
];
});
对于调用factory(Customer::class)->create()
,它运行正常。
但是,如果我想使用factory(Customer::class)->make()
来在内存中创建Customer对象以传递给单元测试,这个工厂将创建一个Hotel对象并持久化到我的数据库中。
是否有一种模式可以帮助Laravel识别factory make()
,并在生成对象时使用不同的方法。比如当我调用factory(Customer::class)->make()
时,它会生成:
'name' => $faker->name,
'phone' => $faker->phoneNumber,
'email' => $faker->email,
然后它会创建一个$hotel = factory(Hotel::class)->make()
,并执行$customer->setRelation('hotel', $hotel)
?
英文:
I have a factory for Customer class
$factory->define(Customer::class, function (Faker $faker) {
return [
'hotel_id' => function() {
return factory(\App\Hotel::class)->create()->id;
},
'name' => $faker->name,
'phone' => $faker->phoneNumber,
'email' => $faker->email,
];
});
It's working fine for calling factory(Customer:class)->create().
However, if I want to factory(Customer:class)->make() to create Customer object in memory to pass to unit tests, this factory will create a Hotel object and persist to my database.
Is there a pattern that helps Laravel to recognize factory make(), and use a different approach when generating objects. Like when I call factory(Customer:class)->make(), it will generate
'name' => $faker->name,
'phone' => $faker->phoneNumber,
'email' => $faker->email,
THEN it will create a $hotel = factory(Hotel:class)->make() and do $customer->setRelation('hotel', $hotel) ?
答案1
得分: 1
你应该将 hotel_id
从工厂的 define
中排除,并改用后续回调函数。
根据文档(我的重点):
工厂回调使用
afterMaking
和afterCreating
方法进行注册,允许您在创建或制作模型后执行其他任务。例如,您可以使用回调将其他模型关联到已创建的模型:
示例
$factory->afterMaking(App\User::class, function ($user, $faker) {
// ...
});
$factory->afterCreating(App\User::class, function ($user, $faker) {
$user->accounts()->save(factory(App\Account::class)->make());
});
https://laravel.com/docs/6.x/database-testing#factory-callbacks
英文:
You should keep the hotel_id
out of the factory define
and use the after callbacks instead.
From the documentation (my emphasis):
> Factory callbacks are registered using the afterMaking and
> afterCreating methods, and allow you to perform additional tasks after
> making or creating a model. For example, you may use callbacks to
> relate additional models to the created model:
Example
$factory->afterMaking(App\User::class, function ($user, $faker) {
// ...
});
$factory->afterCreating(App\User::class, function ($user, $faker) {
$user->accounts()->save(factory(App\Account::class)->make());
});
https://laravel.com/docs/6.x/database-testing#factory-callbacks
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论