2011-12-10 1 views
7

Utilizzo il bundle DoctrineFixtures per creare entità di esempio durante lo sviluppo. Nel mio metodo load() delle fixture ORM, definisco i dati come array associativi e creo l'oggetto entity in un loop.Matrice di mappa all'entità in Symfony2/Doctrine2

<?php 
// ... 
public function load($manager) { 
    $roleDefs = array(
     'role-1' => array(
      'role' => 'administrator' 
     ), 
     'role-2' => array(
      'role' => 'user' 
     ), 
    ); 

    foreach($roleDefs as $key => $roleDef) { 
     $role = new Role(); 
     $role->setRole($roleDef['role']); 
     $manager->persist($role); 

     $this->addReference($key, $role); 
    } 

    $manager->flush(); 
} 

Uso sempre lo stesso schema di array. Ogni elemento dell'array usa il nome della proprietà (nella notazione del trattino basso) dell'entità come indice. Se la struttura dell'entità diventa più complessa, ci sono molte linee $entity->setMyProperty($def['my_property']);.

Penso che il problema della mappatura dei nomi di proprietà ai metodi setter è un problema molto comune in Symfony e Doctrine in quanto questo tipo di mappatura si trova in molte situazioni (ad esempio, mappare i moduli alle entità).

Ora mi chiedo se esiste un metodo incorporato che può essere utilizzato per la mappatura. Sarebbe bello avere una soluzione come

foreach($defs as $key => $def) { 
    $entity = $magicMapper->getEntity('MyBundle:MyEntity', $def); 
    // ... 
} 

Qualcuno ha un'idea di come questo possa essere raggiunto?

Grazie mille, Hacksteak

risposta

14

io a volte usano i loop durante la creazione di infissi. Non sono sicuro che questa soluzione soddisfi le tue esigenze, ma trovo che il modo più flessibile per costruire infissi e aggiungere rapidamente nuove proprietà nel tempo, se necessario, è quello di fare quanto segue ... Supponendo la creazione di un gruppo di post del blog :

// an array of blog post fixture values 
$posts = array(
    array(
     'title' => 'Foo', 
     'text' => 'lorem' 
     'date' => new \DateTime('2011-12-01'), 
    ), 
    array(
     'title' => 'Bar', 
     'text' => 'lorem' 
     'date' => new \DateTime('2011-12-02'), 
    ), 
    // more data... 
); 

// loop over the posts 
foreach ($posts as $post) { 
    // new entity 
    $post = new Post(); 

    // now loop over the properties of each post array... 
    foreach ($post as $property => $value) { 
     // create a setter 
     $method = sprintf('set%s', ucwords($property)); // or you can cheat and omit ucwords() because PHP method calls are case insensitive 
     // use the method as a variable variable to set your value 
     $post->$method($value); 
    } 

    // persist the entity 
    $em->persist($post); 
} 

In questo modo è possibile aggiungere ulteriori proprietà aggiungendo semplicemente i nuovi valori all'array.

+1

Ora sto utilizzando la soluzione con alcune modifiche (supporto per caratteri di sottolineatura e metodi di aggiunta) in classe esterna. – hacksteak25

+1

Ho visto questa risoluzione prima, ma penso che potrebbe risolvere questo problema in modo più flessibile. Che ne dici di idratatori interni? –

+0

Sarei sicuramente interessato ad ascoltare una soluzione più flessibile, quindi sono tutto orecchie! –