教条装置没有坚持,为什么?

时间:2017-08-04 00:46:10

标签: php symfony doctrine-orm

我有一小组Doctrine DataFixtures,设置如下:

$ tree -A code/src/AppBundle/DataFixtures/ORM/
code/src/AppBundle/DataFixtures/ORM/
├── LoadCategoryData.php
├── LoadCategoryHasPostData.php
└── LoadPostData.php

尝试加载灯具时请参阅以下输出:

$ docker exec -u www-data -it coding_webserver_1 php bin/console doctrine:fixtures:load -vvv
Careful, database will be purged. Do you want to continue y/N ?y
  > purging database
  > loading [1] AppBundle\DataFixtures\ORM\LoadCategoryData
  > loading [2] AppBundle\DataFixtures\ORM\LoadPostData
  > loading [3] AppBundle\DataFixtures\ORM\LoadCategoryHasPostData


  [Symfony\Component\Debug\Exception\FatalThrowableError]                                                                                                                                                         
  Type error: Argument 1 passed to AppBundle\Entity\CategoryHasPosts::setCategory() must be an instance of AppBundle\Entity\Category, null given, called in /var/www/src/AppBundle/DataFixtures/ORM/LoadCategory  
  HasPostData.php on line 22

这就是文件LoadCategoryData的样子:

class LoadCategoryData extends AbstractFixture implements OrderedFixtureInterface
{
    public function load(ObjectManager $manager)
    {
        $category_1 = new Category();
        $category_1->setCategoryName('Hot');
        $category_1->setCategoryDescription('Hot Topics');
        $category_1->setSlug('hot');
        $category_1->setActive(true);
        $manager->persist($category_1);

        $category_2 = new Category();
        $category_2->setCategoryName('New');
        $category_2->setCategoryDescription('New Topics');
        $category_2->setSlug('new');
        $category_2->setActive(true);
        $manager->persist($category_2);

        $manager->flush();
    }

    public function getOrder()
    {
        return 1;
    }
}

这是LoadPostData档案的内容:

class LoadPostData extends AbstractFixture implements OrderedFixtureInterface
{
    public function load(ObjectManager $manager)
    {
        $faker = Faker\Factory::create();

        for ($i = 0; $i < 1000; $i++) {
            $post = new Post();
            $post->setPostTitle($faker->sentence);
            $post->setPostContent($faker->paragraph);
            $post->setSlug($faker->slug);

            $manager->persist($post);
        }

        $manager->flush();
    }

    public function getOrder()
    {
        return 2;
    }
}

这是LoadCategoryHasPostData档案的内容:

class LoadCategoryHasPostData extends AbstractFixture implements OrderedFixtureInterface
{
    public function load(ObjectManager $manager)
    {
        for ($i = 0; $i < 2000; $i++) {
            $category_id = random_int(1, 2);
            $category    = $manager->getRepository('AppBundle:Category')->find($category_id);

            $post_id = random_int(1, 2000);
            $post    = $manager->getRepository('AppBundle:Post')->find($post_id);

            $categoryHasPost = new CategoryHasPosts();
            $categoryHasPost->setCategory($category);
            $categoryHasPost->setPost($post);

            $manager->persist($categoryHasPost);
        }

        $manager->flush();
    }

    public function getOrder()
    {
        return 3;
    }
}

我知道为什么这个过程失败了,而且它的逻辑是:前面的实体没有被持久化,这就是我的原因。

为什么CategoryPost没有被持久化和刷新?我在这里缺少什么?

2 个答案:

答案 0 :(得分:1)

试试吧

class LoadCategoryHasPostData extends AbstractFixture implements OrderedFixtureInterface {
    public function load(ObjectManager $manager)
    {
        $categories = $manager->getRepository('AppBundle:Category')->findAll();

        $posts = $manager->getRepository('AppBundle:Post')->findAll();

        for ($i = 0; $i < 2000; $i++) {
            $category = $categories[random_int(0, count($categories) - 1)];
            $post     = $posts[random_int(0, count($posts) - 1);

            $categoryHasPost = new CategoryHasPosts();
            $categoryHasPost->setCategory($category);
            $categoryHasPost->setPost($post);

            $manager->persist($categoryHasPost);
        }

        $manager->flush();
    }

    public function getOrder()
    {
        return 3;
    }
}

答案 1 :(得分:1)

您应该使用引用share entities between fixtures

class LoadCategoryData extends AbstractFixture implements OrderedFixtureInterface
{
    public function load(ObjectManager $manager)
    {
        $category_1 = new Category();
        // …
        $manager->persist($category_1);
        $this->addReference('category_1', $category_1);

        $manager->flush();
    }
    // …
}
class LoadPostData extends AbstractFixture implements OrderedFixtureInterface
{
    public function load(ObjectManager $manager)
    {
        $faker = Faker\Factory::create();

        for ($i = 0; $i < 1000; $i++) {
            $post = new Post();
            $post->setPostTitle($faker->sentence);
            $post->setPostContent($faker->paragraph);
            $post->setSlug($faker->slug);

            $manager->persist($post);
            $this->addReference('post_' . $i, $post);
        }

        $manager->flush();
    }
    // …
}
class LoadCategoryHasPostData extends AbstractFixture implements OrderedFixtureInterface
{
    public function load(ObjectManager $manager)
    {
        $categoryHasPost = new CategoryHasPosts();
        $categoryHasPost->setCategory($this->getReference('category_1'));
        $categoryHasPost->setPost($this->getReference('post_1'));

        $manager->persist($categoryHasPost);

        $manager->flush();
    }
    // …
}