工厂创建具有不同数量关系的多个模型

Posted

技术标签:

【中文标题】工厂创建具有不同数量关系的多个模型【英文标题】:Factory creating multiple models with different number of relationships 【发布时间】:2021-11-26 22:55:19 【问题描述】:

我正在使用以下代码创建 20 个帖子,每个帖子有 3 个 cmets。

Post::factory()
    ->times(20)
    ->has(Comment::factory()->times(3))
    ->create()

相反,我想创建 20 个帖子,每个帖子都有随机数量的 cmets(例如帖子 1 有 2 个 cmets,帖子 2 有 4 个 cmets,等等)

这不起作用,每个帖子都有相同(随机)数量的 cmets。

Post::factory()
    ->times(20)
    ->has(Comment::factory()->times(rand(1, 5)))
    ->create()

我怎样才能做到这一点?

【问题讨论】:

使用变量 $times = rand(1,5); 进行制作,请参阅下面的答案 【参考方案1】:

我会使用工厂方法来做到这一点。像这样向 Post 工厂添加方法:

<?php
namespace Database\Factories\App;

use App\Comment;
use App\Post;
use Illuminate\Database\Eloquent\Factories\Factory;

class PostFactory extends Factory

    public function definition(): array
    
        return [
            // ...
        ];
    

    public function addComments(int $count = null): self
    
        $count = $count ?? rand(1, 5);
    
        return $this->afterCreating(
            fn (Post $post) => Comment::factory()->count($count)->for($post)->create()
        );
    

然后在你的测试中,你可以简单地这样称呼它:

Post::factory()->count(20)->addComments()->create();

【讨论】:

谢谢 miken32。 没问题,似乎是一个更优雅的解决方案,更容易一眼看出发生了什么。【参考方案2】:

更新:应该可以: 灵感来自apokryfos。如果这不起作用,那将:

for($i=0; $i<20; $i++)

    $times = rand(1,5);
    Post::factory()
     ->has(Comment::factory()->times($times))
     ->create();

【讨论】:

好的。也许试试 count($times) -&gt;has(Comment::factory()-&gt;count($times))。如果这不起作用,那将是其他地方的问题。 坦克 Maik Lowrey。效果很好。【参考方案3】:

据我所知,如果您使用-&gt;times,则每个模型不可能有动态数量的相关模型。你可以试试:

collect(range(0,19))
   ->each(function () 
       Post::factory()
          ->has(Comment::factory()->times(rand(1,5)))
          ->create();
);

这应该一个一个地创建 20 个帖子,每个帖子上都有随机数量的 cmets。它可能会慢一点,但可能不会太多

【讨论】:

谢谢apokryfos。效果很好。 超酷!有时你只见树木不见森林!

以上是关于工厂创建具有不同数量关系的多个模型的主要内容,如果未能解决你的问题,请参考以下文章

Laravel/Eloquent - 创建与可能具有或不具有属性的父模型相关的多个子模型的关系

Django:无法创建与一个普通模型具有一对一关系的多个模型对象

Laravel5.3 - 创建一定数量的相关模型 - 创建模型时

Laravel - 向工厂创建的模型添加关系

如何创建具有选择的多个用户模型?

具有多个映射模型的复杂核心数据迁移