php create fixtures with automatic relations

谁都会走 提交于 2019-12-13 07:15:24

问题


I'm currently looking into fixtures for a website with a lot of relations between data.

Let's say there is a league table which is in relation with teams table which is in relation with members table. I briefly checked Alice library to handle data "randomization" and other stuff.

But I have a question whether there is a library (or way), that would allow me to create "dependent" fixtures?

For example I would set template for league to automatically create 20 teams where each team would automatically create 10 members based on some defined structure.

Whenever I call create league fixture, it would create all the dependencies.


回答1:


As mentioned in the official documentation you can have object references in your fixtures

    $userAdmin = new User();
    $userAdmin->setUsername('admin');
    $userAdmin->setPassword('test');

    $manager->persist($userAdmin);
    $manager->flush();

    $this->addReference('admin-user', $userAdmin);

    // in another fixture

    $userGroupAdmin = new UserGroup();
    $userGroupAdmin->setUser($this->getReference('admin-user'));



回答2:


Like Flask wrote above, use Doctrine DataFixtures.

Save yourself time and avoid Alice Bundle / library. I used it on a project in beginning, but had to remove it soon. You simply do not have enough control over generated data.

  • For example you want 3 random players in a team, everything okay, but there is no way to say that they must be unique. At least that was one of the scenarios I had most problems with.

But yes, use faker library.

Another advice that I would give you, implement something like a ->initSeed() method in each of your Fixtures class, which you call at the beginning of the ->load() method. It will call something like this:

$this->faker->seed(100);

Also make your fixtures implement OrderedFixtureInterface, so you have control what is inserted first. Here's the catch... you implement the initSeed() inside load(), NOT inside constructor, because constructor is called in the beginning on all classes, because getOrder() method is needed to find out priority. This way if you add another randomized property at the end of fixture file, the file which comes next, will still generate the same data, so fixture files will not be dependant between themselves.

If you need any code example, let me know, I can help.


Code for saving references:

In the LoadTeamData fixture class, have a constant:

const NUM = 10;

So, you can access it in other fixture file.

When you generate teams in a for loop, use index $i to save the reference.

// Generate teams
for ($i=0; $i<self::NUM; $i++) {
    $team = new Team();
    // ... set things
    $this->setReference('team-'.$i, $team)
    $manager->persist($team);
}

$manager->flush();

Then inside LoadPlayerData for example:

// For each team, generate some players
for ($t=0; $t<LoadTeamData::NUM; $t++) {
    $team = $this->getReference('team-'.$t);
    for ($i=0; $i<self::NUM; $i++) {
        $player = new Player($team);
        // ... set things
        $manager->persist($player);
    }
}

$manager->flush();


来源:https://stackoverflow.com/questions/38122653/php-create-fixtures-with-automatic-relations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!