php 向Laravel Factory模型添加关系

jc3wubiy  于 2022-12-17  发布在  PHP
关注(0)|答案(7)|浏览(142)

我正尝试向工厂模型添加一个关系,以执行一些数据库播种,如下所示-注意,我正尝试向每个用户添加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

我认为这与保存一个集合有关。如果通过分别调用post的每个工厂模型来重写代码,它似乎可以工作。显然,这不是很优雅,因为如果我想持久化10或post给每个用户,那么我必须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());
   });
}

已更新

有没有办法把模型工厂嵌套到第三层?

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());
          }));
   });
}
6uxekuva

6uxekuva1#

自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个职位,每个职位有一个评论。

nr9pn0ug

nr9pn0ug2#

试试这个。对我很有效:

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());
            });
xuo3flqw

xuo3flqw3#

对于第三层嵌套关系,如果您想创建具有正确的对应外键的数据,您可以循环遍历创建帖子的所有结果,如下所示:

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());
        });
});
cfh9epnr

cfh9epnr4#

要回答最初的问题/错误消息:
这个问题确实与保存数据有关。您的代码:

$u->posts()->save(factory(App\Post::class, 2)->make());

...应改为

$u->posts()->saveMany(factory(App\Post::class, 2)->make());

来自laravel文件:
您可以使用createMany方法创建多个相关模型:
$user-〉posts()-〉createMany(工厂(应用程序\帖子::类,3)-〉make()-〉toArray());

这意味着

  • 当只使用工厂创建一个模型时,应使用保存()或create()
  • 当使用工厂创建多个模型时,应该使用saveMany()或createMany()
wlwcrazw

wlwcrazw5#

$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)]
];
});
mw3dktmi

mw3dktmi6#

**让我来解释一下如何通过新学校和旧学校的概念在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的。还有一种方法叫Magic方法。让我解释一下:

\App\Models\Author::factory()->hasArticles(1)->hasComments(9)->hasReplies(2)->create();

hasArticles()是父模型中关系的方法名称,应使用has转换名称。例如:将comments()转换为hasComments()
现在让我们来解释一下在某些情况下仍然很好的老学校,仍然与拉腊维尔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()如果你想要的到不保存在数据库为测试目的.
好好享受。

fslejnso

fslejnso7#

在版本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()
        ];
    }
}```

相关问题