简体   繁体   中英

How to insert dummy data via fixtures to foreign column symfony

I have two enity user and post . I am trying to dump dummy data to post table using fixtures. Now, problem is that I could not insert data to author column which holds ManyToOne relation with User entity.

I tried to insert dummy data by passing id directly as follows:

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

            $post = new Post();
            $post->setTitle($this->faker->realText(20));
            $post->setContent($this->faker->text);
            $post->setIsPublished(true);
            $post->setAuthor('1');
            $post->setPublishedAt(new \DateTime());
            $post->setCreatedAt(new \DateTime());
            $post->setUpdatedAt(new \DateTime());
            $manager->persist($post);

            $manager->flush();
        }

But, it is generating error:

Argument 1 passed to App\Entity\Post::setAuthor() must be an instance of App\Entity\User or null, string given

Is there any way to pick one of user from User entity and insert it into the column randomly.

Update:

After looking at this documentation, I am able to provide reference

UserFixtures:

    public const ADMIN_USER_REFERENCE = 'admin-user';

    public function load(ObjectManager $manager)
    {
        ......
        $this->addReference(self::ADMIN_USER_REFERENCE, $userAdmin);
    }

PostFixtures:

$post->setAuthor($this->getReference(UserFixtures::ADMIN_USER_REFERENCE ));

Following, this way it is setting all the posts to the same author. However, I am looking to insert different author randomly throughout different posts.

in this case, you have to use reference Symfony Fixtures DOC

Sharing Objects between Fixtures¶

For example, when you create an Author, you can "save" it as a reference like this :

$this->addReference('author-reference', $author);

Then in your other fixture that needs a reference to Author you can do something like this :

$author = $this->getReference('author-reference');

I hope this help you, regards

In order to do this I have a BaseFixture class that has a createMany function

protected function createMany(string $classname, int $count, callable $factory)
{
    for ($i = 0; $i < $count; $i++) {
        $entity = new $classname();
        $factory($entity, $i);

        $this->manager->persist($entity);

        $this->addReference($classname.'_'.$i, $entity);
    }
}

and a getRandomReference function :

protected function getRandomReference(string $className)
{
    if (!isset($this->referencesIndex[$className])) {
        $this->referencesIndex[$className] = [];
        foreach ($this->referenceRepository->getReferences() as $key => $ref) {
            if (strpos($key, $className.'_') === 0) {
                $this->referencesIndex[$className][] = $key;
            }
        }
    }
    if (empty($this->referencesIndex[$className])) {
        throw new \Exception(sprintf('Cannot find any references for class "%s"', $className));
    }
    $randomReferenceKey = $this->faker->randomElement($this->referencesIndex[$className]);

    return $this->getReference($randomReferenceKey);
}

Now let's say I want to create fixtures for a company class and an address class,

I will first generate the fixtures for the address :

class AddressFixtures extends BaseFixture {
    public function loadData {
        this->createMany(Address::class, 30, function(Address $address, $count) {
       $address->setDescription($this->faker->paragraph);
       ...

        });
    }
}

Because I used the createMany class from the base class the references are now added automatically for each fixture.

we can now get random addresses for our Company fixtures by using the getRandomReference function from our base class :

class CompanyFixtures extends BaseFixture implements DependentFixtureInterface
{
    public function loadData(ObjectManager $manager)
    {
        $company = new Company();
        $company->setAddress($this->getRandomReference(Address::class));
    }
}

I just want to point out that most of this if not all (I can't exactly remember it has been a while) comes from a symfonyCasts tutorial I followed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM