[英]Adding Relations to Laravel Factory Model
我正在尝试添加与工厂 model 的关系以执行一些数据库播种,如下所示 - 注意我正在尝试向每个用户添加 2 个帖子
public function run()
{
factory(App\User::class, 50)->create()->each(function($u) {
$u->posts()->save(factory(App\Post::class, 2)->make());
});
}
但它抛出以下错误
Argument 1 passed to Illuminate\Database\Eloquent\Relations\HasOneOrMany::s
ave() must be an instance of Illuminate\Database\Eloquent\Model, instance
of Illuminate\Database\Eloquent\Collection given
我认为这与保存收藏有关。 如果通过分别为帖子调用每个工厂 model 来重新编写代码,它似乎可以工作。 显然这不是很优雅,因为如果我想坚持 10 或发布给每个用户,那么我必须 decalare 10 或行,除非我使用某种 for 循环。
public function run()
{
factory(App\User::class, 50)->create()->each(function($u) {
$u->posts()->save(factory(App\Post::class)->make());
$u->posts()->save(factory(App\Post::class)->make());
});
}
* 更新 *
有没有办法将 model 工厂嵌套到第三层深?
public function run()
{
factory(App\User::class, 50)
->create()
->each(function($u) {
$u->posts()->saveMany(factory(App\Post::class, 2)
->make()
->each(function($p){
$p->comments()->save(factory(App\Comment::class)->make());
}));
});
}
从 Laravel 5.6 开始,有一个afterCreating 和 afterMaking回调函数允许你在创建/制作后直接添加关系:
$factory->afterCreating(App\User::class, function ($user, $faker) {
$user->saveMany(factory(App\Post::class, 10)->make());
});
$factory->afterMaking(App\Post::class, function ($post, $faker) {
$post->save(factory(App\Comment::class)->make());
});
现在
factory(App\User::class, 50)->create()
会给你 50 个用户,每个用户有 10 个帖子,每个帖子有一个评论。
尝试这个。 它对我有用:
factory(\App\Models\Auth\User::class, 300)->create()->each(function ($s) {
$s->spots()->saveMany(factory(\App\Models\Spots\Parking::class, 2)->create()->each(function ($u) {
$u->pricing()->save(factory(\App\Models\Payment\Pricing::class)->make());
}));
$s->info()->save(factory(\App\Models\User\Data::class)->make());
});
对于第 3 级嵌套关系,如果要使用适当的相应外键创建数据,可以遍历创建帖子的所有结果,如下所示:
factory(App\User::class, 50)->create()->each(function($u) {
$u->posts()
->saveMany( factory(App\Post::class, 2)->make() )
->each(function($p){
$p->comments()->save(factory(App\Comment::class)->make());
});
});
要回答最初的问题/错误消息:
问题确实与保存数据有关。 您的代码:
$u->posts()->save(factory(App\Post::class, 2)->make());
...应该改为
$u->posts()->saveMany(factory(App\Post::class, 2)->make());
来自Laravel 文档:
您可以使用 createMany 方法创建多个相关模型:
$user->posts()->createMany( factory(App\\Post::class, 3)->make()->toArray());
这意味着:
$factory->define(User::class, function (Faker $faker) {
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', //
password
'remember_token' => Str::random(10),
];
});
$factory->define(Post::class, function ($faker) use ($factory) {
return [
'title' => $faker->sentence(3),
'content' => $faker->paragraph(5),
'user_id' => User::pluck('id')[$faker->numberBetween(1,User::count()-1)]
];
});
让我解释一下如何在 Laravel 中添加调用工厂的多级关系 9 通过新学校和旧学校的概念。 新学校是:
\App\Models\Author::factory()
->has(
\App\Models\Article::factory(1)
->has(
\App\Models\Comment::factory(9)
->has(
\App\Models\Reply::factory(2)
)
))->create();`enter code here`
那是 Laravel 9. 有 anthor 方法调用 Magic 方法。 让我解释一下:
\App\Models\Author::factory()->hasArticles(1)->hasComments(9)->hasReplies(2)->create();
这个hasArticles()
是父类 model 中关系方法的名称,应该将名称转换为 has。 例如: comments()
转换为hasComments()
。
现在让我们解释一下在某些情况下仍然很完美并且仍然适用于 Laravel 9 的旧学校。
\App\Models\Author::factory(1)->create()
->each(function($a) {
$a->articles()->saveMany( \App\Models\Article::factory(2)->create() )
->each(function($p){
$p->comments()->saveMany(\App\Models\Comment::factory(5))->create()
->each(function($r){
$r->replies()->saveMany(\App\Models\Reply::factory(5))->create();
});
});
});
当然,您可以将方法saveMany()
替换为save()
作为您的关系。 如果您不想出于测试目的保存在数据库中,也可以将方法create()
替换为make()
。
享受。
在版本laravel 9中,这样使用
<?php
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Post>
*/
class PostFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition()
{
return [
'user_id' => User::factory(),
'title' => fake()->paragraph()
];
}
}```
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.