首页 > 解决方案 > Symfony 5: Fixtures & Factories - 如何设置关系 (oneToMany<->ManytoOne)

问题描述

我是 Symfony 的新手,在生成假数据时有些迷失......

我有一个问题实体和一个答案实体。一个问题可以有多个答案,一个答案属于一个问题。

当简单地在夹具中手动启动所有内容(提出新问题、设置内容、回答和设置问题、坚持和刷新)时,一切正常,但我想使用工厂将它提升到一个新的水平。

在设置工厂并尝试运行固定装置时,我偶然发现了有关如何设置生成答案的关系的问题(无法设置关系,我使 fk 列不可为空,因为没有问题就不能存在答案)。

一种不持久的解决方法

我保留了更新的简化并从 QuestionRepository 中删除了额外的功能(不再需要)。然后,我在我的答案实体中再次使 fk 列 (question_id) 可以为空。执行夹具工作,所有答案都与问题有关。不完全令人满意,因为不应该让答案毫无疑问,所以这真的很“丑陋”->所以设置关系有效,但现在“为时已晚”

更新

我试图在 TaskFactory.php 中简化它(没有成功):
protected function getDefaults(): array
{
    $questionRepository = $this->entityManager->getRepository(Question::class);

    return [
        'name' => self::faker()->sentence(),
        'description' => self::faker()->text('20'),
        'question' => $questionRepository->findOneBy(['id'=>rand(1,5)])
    ];
}

我试过的

答案工厂.php:

protected function initialize(): self
    {
        // deal with the relation of answer to question before saving
        return $this
            ->afterInstantiate(function(Answer $answer) {
                $questionRepository = $this->entityManager->getRepository(Question::class);
                if(!$answer->getQuestion()){
                    $answer->setQuestion($questionRepository->getEntityById(rand(1,5)));
                }
            })
        ;
    }

QuestionRepository.php

public function getEntityById($id){
    return $this->createQueryBuilder('t')
        ->andWhere('t.id = :id')
        ->setParameter('id', $id)
        ->getQuery()
        ->getOneOrNullResult();
}

AppFixtures.php

class AppFixtures extends Fixture
{
    public function load(ObjectManager $manager)
    {
        QuestionFactory::new()->createMany(5);
        AnswerFactory::new()->createMany(12);
    }
}

我的目标是随机分配问题的答案。

尝试运行时,symfony console doctrine:fixtures:load 我仍然得到完整性约束违规,即“question_id”不能为空,因此关系没有明显设置。

那么,我错过了什么/错过了理解

标签: phpsymfonyrelationshipfactory

解决方案


推荐阅读