【问题标题】:How to create fixture where there is relation between two tables in Symfony?如何在 Symfony 中的两个表之间创建有关系的夹具?
【发布时间】:2019-08-15 15:33:09
【问题描述】:

我有两个实体,分别是“用户”和“地址”,它们之间存在“OneToOne”关系。

用户表有一列'address_id'是外键,存储地址表的id . 我尝试使用 2 种不同的方法创建夹具:

方法一:

AddressFixture.php

namespace App\DataFixtures;

use App\Entity\Address;
use App\Entity\User;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

class AddressFixture extends Fixture
{
    public function __construct(UserPasswordEncoderInterface $encoder)
    {
        $this->encoder = $encoder;
    }
    public function load(ObjectManager $manager)
    {
        $address = new Address();
        $address->setStreet('Sai Apartment');
        $address->setCity('Noida');
        $address->setState('Uttar Pradesh');
        $address->setCountry('India');
        $address->setPincode('201301');
        $manager->persist($address);
        $manager->flush();
        if (null != $address->getId()) {
            $user = new User();
            $user->setFName('Kumar');
            $user->setLName('Saurabh');
            $user->setUsername('supa-admin');
            $user->setPassword(
                $this->encoder->encodePassword($user, 'querty')
            );
            $user->setEmail('some_email@gmail.com');
            $user->setAddress($address);
            $user->setContact(78954);
            $user->setGender('male');
            $user->setAge(26);

            $user->persist($user);
            $manager->flush();
        }
    }
}

方法二:

在此我创建了两个不同的 Fixtures:

AddressFixture.php

namespace App\DataFixtures;

use App\Entity\Address;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

class AddressFixture extends Fixture
{
    public function load(ObjectManager $manager)
    {
        $address = new Address();
        $address->setStreet('Sai Apartment');
        $address->setCity('Noida');
        $address->setState('Uttar Pradesh');
        $address->setCountry('India');
        $address->setPincode('201301');
        $manager->persist($address);
        $manager->flush();
    }
}

UsersFixture.php

namespace App\DataFixtures;

use App\Entity\User;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

class AddressFixture extends Fixture
{
    public function __construct(UserPasswordEncoderInterface $encoder)
    {
        $this->encoder = $encoder;
    }
    public function load(ObjectManager $manager)
    {
            $user = new User();
            $user->setFName('Kumar');
            $user->setLName('Saurabh');
            $user->setUsername('supa-admin');
            $user->setPassword(
                $this->encoder->encodePassword($user, 'querty')
            );
            $user->setEmail('some_email@gmail.com');
            $user->setAddress($address);
            $user->setContact(78954);
            $user->setGender('male');
            $user->setAge(26);

            $user->persist($user);
            $manager->flush();
    }
}

然后我跑了:

$ php bin/console 学说:fixtures:load

两种方式都没有给我所需的结果。两个表之间使用外键时如何创建Fixtures?

【问题讨论】:

  • 第一个看起来不错 - 您可以删除 if (null != $address->getId()) 部分并在创建并保留两个实体后只执行一次刷新。或者在第一个版本中究竟有什么不适合您?如果您想使用单独的装置,您应该看看如何订购装置以及如何从doctrine sharing objects between fixtures 访问以前创建的实体
  • 有一个小错误$user->persist($user);。在方法1中应该是$manager->persist($user);
  • @Constantin:感谢好友指出。这是我的一个愚蠢的错误。
  • 在方法 2 中,在文件 UsersFixture.php 中,应将类命名为 UsersFixture 而不是 AddressFixture 。另外我不明白变量$address 的来源。您可以使用$manager 查找您的$address 实体。

标签: symfony orm doctrine django-fixtures symfony-4.2


【解决方案1】:

您应该在您的UserFixture 中实现DependentFixtureInterface

class UserFixture extends Fixture implements DependentFixtureInterface
{

   public function getDependencies()
    {
        return [
            AddressFixture::class,
        ];
    }

}

因此,当您尝试为您的用户获取参考时,SymfonyFixturesLoader 将加载所有依赖项。然后在您的UserFixture 中将其注入您的地址字段:

public function load(ObjectManager $manager)
{
   $user = new User();
   // ...
   $user->setAddress($this->getReference(AddressFixture::FIRST_ADDRESS));
}

不要忘记在 AddressFixture 端设置参考:

public function load(ObjectManager $manager)
{
   $address = new Address();
   // ...
   $this->setReference(self::FIRST_ADDRESS, $address);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-04
    • 2016-05-22
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多