簡體   English   中英

添加關系到 Laravel 工廠 Model

[英]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());

這意味着:

  • 當只用工廠創建一個模型時,你應該使用 save() 或 create()
  • 使用工廠創建多個模型時,應使用 saveMany() 或 createMany()
$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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM