根据Laravel的documentation on defining relationships within model factories:
您还可以使用工厂定义中的Closure属性将关系附加到模型。例如,如果您想在创建帖子时创建新的用户实例,则可以执行以下操作:
$factory->define(App\Post::class, function ($faker) {
return [
'title' => $faker->title,
'content' => $faker->paragraph,
'user_id' => function () {
return factory(App\User::class)->create()->id;
}
];
});
我遇到的问题是关系定义中对create()
的引用。在我看来,这并不属于这里。
如果我想要将我的关系持久保存到数据库中,它会很有效:
factory(App\Post::class)->create();
通过直接在此上方运行代码,将创建一个新的App\Post
和一个新的App\User
,并且这两个代码都会持久保存到数据库中。
但是,如果我只是想new
模型,而不是通过运行来保持任何(根本没有)数据库:
factory(App\Post::class)->make();
它完成了我想要的某一点。新的App\Post
实例已创建但未保留,但创建了App\Comment
并将其保留到数据库中。
在我看来,我真正想要的是这样的事情:
$factory->define(App\Post::class, function ($faker) {
return [
'title' => $faker->title,
'content' => $faker->paragraph,
'user_id' => function () {
// here I only want to declare the relationship,
// not decide whether I want to create() or make()
// the relationship, something like:
return factory(App\User::class)->createOrMake()->id;
// or perhaps something like:
return factory(App\User::class)->id;
}
];
});
最终结果是我希望相关数据能够尊重我在呼叫顶部尝试做的事情。做一切。或创造一切。
我在这里做错了吗?或者这是目前还没有的东西?
谢谢!
答案 0 :(得分:1)
你想要你的相关模型的lazy()方法!
至少在Laravel 5.5中。
我在这里找到了你的问题,因为我遇到了同样的问题。我找到了答案,感谢Laravel精心编写的代码 - lazy()被定义在make()XDebug带我去的上方 - 我已经尝试过了,它似乎有效。
这就是我正在做的事情:
$factory->define(App\ArtItem::class, function (Faker $faker) {
return [
// 'id' => $faker->randomDigit,
'slug' => $faker->unique->word,
'artist_id' => factory(App\Artist::class)->lazy(),
'image_id' => factory(App\Image::class)->lazy(),
'created_at' => $faker->dateTime,
'updated_at' => $faker->dateTime,
'deleted_at' => $faker->dateTime,
];
});
Lazy()是一个有趣的生物,它返回一个闭包,所以你不能factory(App\Image::class)->lazy()->id
,但我仍然看到它成功设置了正确的image_id和artist_id。
我当然希望你在此之前很久就找到了解决方案,但也许这会帮助其他人!
答案 1 :(得分:0)
尝试这种方法
我和你的问题一样,这个解决方案对我有用,但找不到原因。
Customerid:(5 input)
123
123
234
123
234
Output(Expected)
123
234
Actual:
123
123
123
234
答案 2 :(得分:0)
现在终于可以使用Laravel 5.6.12中添加的Factory Callbacks解决了这个问题。
$factory->afterMaking(Post::class, static function (Post $post) {
if (!$post->user_id) {
$post->user()->associate(factory(User::class)->make(['id' => 0]));
}
});
$factory->afterCreating(Post::class, static function (Post $post) {
if (!$post->user_id) {
$post->user()->associate(factory(User::class)->create())->save();
}
});
现在,无论何时make
个帖子,如果不传递它的user_id,它将为您make
个用户,并设置关系而不保存它。但是,如果您create
个帖子,它将把一个新用户持久保存到数据库中,并将其ID保存到帖子模型中。
请注意,afterMaking
和afterCreating
闭包在create
工厂模型中同时被调用。我暂时将用户ID设置为0,以防外键posts.user_id
被定义为not null
。它将被更新为afterCreating
中的正确值。这是一个可怕的骇客,但直到我们获得一个合适的beforeCreating
钩子,该钩子才允许我们首先创建相关模型。