venerdì 25 marzo 2011

Utilizzare fixtures in Symfony2, Doctrine2

Articolo modificato il 1 Maggio 2011 per far funzionare il tutto con la versione Beta1 e, si spera, successive di Symfony2.

Ho voluto provare ad implementare il caricamento di fixtures in FooAppsHelloBundle per consentire ai più pigri di avere una lista predefinita di amici da salutare senza bisogno di inserirli manualmente. La prima cosa da dire è che in Symfony2 non viene più supportato il caricamento di fixtures da file YAML come in symfony1, bisogna quindi aggiungere al proprio bundle una classe che svolga questo compito.

Per chi, come ho fatto io per questi primi esperimenti, utilizza Symfony Standard Edition si presenta un ulteriore problema in quanto nella distribuzione non è stata inclusa l'estensione di Doctrine2 necessaria. Per prima cosa dalla cartella del progetto si deve eseguire questo comando

git clone git://github.com/doctrine/data-fixtures.git vendor/doctrine-data-fixtures

Chi non ha git (ma converrebbe iniziare ad imparare ad usarlo), può ottenere il pacchetto da GitHub.

Per le ragioni viste nell'articolo precedente bisogna anche registrare il namespace

// app/autoload.php

/* ... */
$loader->registerNamespaces(array(
    'Symfony'            => array(__DIR__.'/../vendor/symfony/src', __DIR__.'/../vendor/bundles'),
    'Sensio'             => __DIR__.'/../vendor/bundles',
    'JMS'                => __DIR__.'/../vendor/bundles',
    /* Aggiungere la riga seguente */
    'Doctrine\\Common\\DataFixtures'   => __DIR__.'/../vendor/doctrine-data-fixtures/lib',
    /* ... */
));

A partire dalla versione Beta1 di Symfony2, il comando per il caricamento di fixtures si trova in un bundle separato DoctrineFixturesBundle che bisogna installare perché non incluso nella versione Standard.

git clone git://github.com/symfony/DoctrineFixturesBundle.git vendor/bundles/Symfony/Bundle/DoctrineFixturesBundle

Il bundle va poi registrato

// app/AppKernel.php

    public function registerBundles()
    {
        return array(
            /* ... */
            new Symfony\Bundle\DoctrineFixturesBundle\DoctrineFixturesBundle(),
        );
    }

Si può a questo punto creare la nostra classe per il caricamento delle fixtures.

// src/FooApps/HelloBundle/Fixtures/ORM/HelloFixtures.php

namespace FooApps\HelloBundle\Fixtures\ORM;

use Doctrine\Common\DataFixtures\FixtureInterface;
use FooApps\HelloBundle\Entity\Friend;

class HelloFixtures implements FixtureInterface
{
    public function load($manager)
    {
        $friend = new Friend();
        $friend->setName('Fabien');
        $manager->persist($friend);

        /* Creare altre istanze di Friend qui se necessario */

        $manager->flush();
    }
}

Cosa succede nel metodo load() dovrebbe essere abbastanza chiaro: si creano le istanze dell'entità Friend, se ne impostano le proprietà, se ne chiede la persistenza sul database all'entity manager, infine flush() (notare che viene invocato una sola volta alla fine) salva fisicamente i dati sul database.

Fatto tutto questo è possibile usare il seguente comando

php app/console doctrine:fixtures:load --fixtures=src/FooApps/HelloBundle/DataFixtures/ORM

Se si omette l'opzione --fixtures, saranno caricate con un solo comando le fixtures di tutti i bundle del progetto per i quali sia definita una classe loader.

Nessun commento:

Posta un commento

Nota. Solo i membri di questo blog possono postare un commento.