Environment specific data fixtures with Symfony+Doctrine

前端 未结 2 856
失恋的感觉
失恋的感觉 2021-01-31 19:07

With Smyfony2 and Doctrin2, data fixtures can be created using the following example: http://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html

What I wou

相关标签:
2条回答
  • 2021-01-31 19:54

    The easiest way is to put your fixtures into different folders and then load them with the php app/console doctrine:fixtures:load --fixtures=../src/Acme/TestBundle/DataFixtures/ORM/test command. The fixtures option must point to the relative path from where you app folder!

    You can then split up your data into initial, test and so on or create dev, test, staging, prod fixtures, just as you like.

    If you want to mix them up, I don't know any better solution than what I did: I createt a "templates" folder where all fixtures reside in. In my dev folder, I create one class which extends the proper fixture class from template and adjusts what is needed to adjust (like overriding the getOrder method). It's not perfect and I guess one could think about extending the fixtures:load command to take multiple paths, but it works for me.

    0 讨论(0)
  • 2021-01-31 19:57

    An alternative to breaking out fixtures by directory is to use a custom fixture class. Your fixture classes would then extend this class and specify the environments it will actually be loaded in.

    <?php
    
    use Doctrine\Common\DataFixtures\FixtureInterface;
    use Doctrine\Common\Persistence\ObjectManager;
    use Symfony\Component\DependencyInjection\ContainerAwareInterface;
    use Symfony\Component\DependencyInjection\ContainerInterface;
    use Symfony\Component\HttpKernel\KernelInterface;
    
    /**
     * Provides support for environment specific fixtures.
     *
     * This container aware, abstract data fixture is used to only allow loading in
     * specific environments. The environments the data fixture will be loaded in is
     * determined by the list of environment names returned by `getEnvironments()`.
     *
     * > The fixture will still be shown as having been loaded by the Doctrine
     * > command, `doctrine:fixtures:load`, despite not having been actually
     * > loaded.
     *
     * @author Kevin Herrera <kevin@herrera.io>
     */
    abstract class AbstractDataFixture implements ContainerAwareInterface, FixtureInterface
    {
        /**
         * The dependency injection container.
         *
         * @var ContainerInterface
         */
        protected $container;
    
        /**
         * {@inheritDoc}
         */
        public function load(ObjectManager $manager)
        {
            /** @var KernelInterface $kernel */
            $kernel = $this->container->get('kernel');
    
            if (in_array($kernel->getEnvironment(), $this->getEnvironments())) {
                $this->doLoad($manager);
            }
        }
    
        /**
         * {@inheritDoc}
         */
        public function setContainer(ContainerInterface $container = null)
        {
            $this->container = $container;
        }
    
        /**
         * Performs the actual fixtures loading.
         *
         * @see \Doctrine\Common\DataFixtures\FixtureInterface::load()
         *
         * @param ObjectManager $manager The object manager.
         */
        abstract protected function doLoad(ObjectManager $manager);
    
        /**
         * Returns the environments the fixtures may be loaded in.
         *
         * @return array The name of the environments.
         */
        abstract protected function getEnvironments();
    }
    

    Your fixtures would end up looking like this:

    <?php
    
    namespace Vendor\Bundle\ExampleBundle\DataFixtures\ORM;
    
    use AbstractDataFixture;
    use Doctrine\Common\Persistence\ObjectManager;
    
    /**
     * Loads data only on "prod".
     */
    class ExampleData extends AbstractDataFixture
    {
        /**
         * @override
         */
        protected function doLoad(ObjectManager $manager)
        {
            // ... snip ...
        }
    
        /**
         * @override
         */
        protected function getEnvironments()
        {
            return array('prod');
        }
    }
    

    I believe that this should work with both ORM an ODM data fixtures.

    0 讨论(0)
提交回复
热议问题