doctrine / data-fixtures

Doctrine2 ORM Data Fixtures Extensions
http://www.doctrine-project.org
MIT License
2.77k stars 224 forks source link

Handle random and unique references #363

Closed ghost closed 3 years ago

ghost commented 3 years ago

Hello, would you be interested in these features? I wrote the tests and the doc. It probably needs an outside look to see if these additions are relevant and if they are integrated properly. You can tag me if there is any maintenance or bug to fix in the future.

Thanks for your work by the way!

From README.md:

Random references

You can call a random reference. To do this, you will need to define a set of references with a common tag.

For instance:

namespace MyDataFixtures;

use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Persistence\ObjectManager;

class UserRoleDataLoader extends AbstractFixture
{
    public function load(ObjectManager $manager)
    {
        for ($i=0; $i < 10; $i++) {
            $role = new Role();
            $role->setName('name-'.$i);

            $manager->persist($role);

            // store tagged Reference of current role for other Fixtures
            $this->addReference('role-'.$i, $role, 'role');
        }

        $manager->flush();
    }
}

Get a random Role reference for User.

namespace MyDataFixtures;

use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Persistence\ObjectManager;

class UserDataLoader extends AbstractFixture
{
    public function load(ObjectManager $manager)
    {
        $user = new User();
        $user->setUsername('jwage');
        $user->setPassword('test');
        $user->setRole(
            $this->getRandomReference('role') // load the stored reference
        );

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

Unique references

You can generate unique references made obsolete after use. This ensures that you do not reuse unique references for a given context (tag). Unique references are invalidated only within the scope of the assigned tag:

$this->addUniqueReference('ref-a', $ref, 'tag-a');
$this->addUniqueReference('ref-a', $ref, 'tag-b');

$this->getUniqueReference('ref-a', 'tag-a');

// ->getUniqueReference('ref-a', 'tag-a'); // obsolete
// ->getUniqueReference('ref-a', 'tag-b')  // still valid

You can't assign a tag to unique references already assigned to non-unique references and vice versa.

Calling ->getRandomReference for a tag assigned to unique references returns a unique reference immediately made obsolete. Of course, you must create enough unique references for your needs, otherwise an exception will be thrown.

Usage example: You want to generate Actor and Role fixtures. A role cannot be assigned to several actors, so your references must be unique.

namespace MyDataFixtures;

use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Persistence\ObjectManager;

class ActorRoleDataLoader extends AbstractFixture
{
    public function load(ObjectManager $manager)
    {
        for ($i=0; $i < 10; $i++) {
            $role = new Role();
            $role->setName('name-'.$i);

            $manager->persist($role);

            // store unique Reference of current role for other Fixtures
            // you just have to tag it
            $this->addUniqueReference('role-'.$i, $role, 'role');
        }

        $manager->flush();
    }
}

Actors fixtures:

namespace MyDataFixtures;

use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Persistence\ObjectManager;

class ActorDataLoader extends AbstractFixture
{
    public function load(ObjectManager $manager)
    {
        $actor = new Actor();
        $actor->setUsername('Franck');
        $actor->setRole(
            $this->getUniqueReference('role-1', 'role')
            // or $this->getRandomReference('role')
        );

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