2016-04-29 19 views
7

Ich benutze Symfony2 mit Doctrine und ich benutze das Alice Fixture Bundle, um meine Fixtures zum Testen zu generieren.Kann ich die automatische Inkrement-ID mit Alice Fixtures überschreiben?

In einem Fall muss ich ein Fixture erstellen, wo die ID 148 für einen bestimmten Test ist. Alle unsere IDs sind auf auto_increment konfiguriert, daher erstelle ich derzeit 147 Dummy-Datensätze, um genau die zu erstellen, die ich brauche.

Ich hatte gehofft, diese Definition zu verwenden, um die ID zu zwingen, auf 148 zu setzen:

invoiceClassNoClass (extends invoiceClass): 
    id: 148 
    sortOrder: 1 
    label: 'No Class' 

Leider funktioniert das nicht. Von einer Google-Suche las ich einen kurzen Kommentar, der besagt, dass ich zuerst eine setId-Methode zu meiner Entität hinzufügen muss. Ich habe es versucht, aber es hat keinen Unterschied gemacht. In Wirklichkeit möchte ich nicht als setId-Methode hinzufügen, wenn ich es nicht brauche, da es gegen unsere Integritätsregeln verstößt, bei denen wir niemals die Einstellung einer ID erlauben.

Vielleicht gibt es eine Reflexionsklasse, die verwendet werden könnte? Vielleicht ist das in Alice eingebaut und ich weiß es nicht?

+0

* Ich muss zuerst eine setId Methode zu meiner Einheit hinzuzufügen. Ich habe es versucht, aber es hat keinen Unterschied gemacht. * Bitte erläutern Sie es genauer, haben Sie einen Fehler bekommen? Das Hinzufügen von 'setId' ist wahrscheinlich die beste und einfachste Lösung für Ihr Problem. –

+0

Der ID-Generatortyp überschreibt eine Einstellung, die Sie mit setId festgelegt haben, daher reicht es nicht aus, nur das Objekt zu setzen. – David

+0

@ David Sind Sie sicher? IIRC, automatische Inkrementierung wird nur verwendet, wenn die primäre ID null ist. –

Antwort

6

Wenn Sie möchten, dass die Doktrin einen bestimmten Wert für eine automatische Inkrement-ID speichert, müssen Sie die automatische Inkrementierung in Dokeminetadaten deaktivieren. Siehe

Explicitly set Id with Doctrine when using "AUTO" strategy

$this->em->persist($entity); 

$metadata = $this->em->getClassMetaData(get_class($entity)); 
$metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator()); 
+0

Mit anderen Worten, können wir sagen, dass dieser Code notwendig ist, um eine 'setId()' Funktion aufrufen zu können? –

+1

Nein, Sie können setId auch ohne diesen Code aufrufen, aber doctrine ignoriert nur Ihren ID-Wert und verwendet weiterhin den automatischen Inkrementwert. –

+0

Danke, das habe ich mir gedacht, mein Satz war schlecht formuliert. –

5

UPDATE: Nach weiterer Forschung zu diesem Thema, erkennen ich, dass hartzucodieren ids in Leuchten mit seinen eigenen Problemen kommt und ist in der Regel keine gute Idee. Stattdessen ist es besser, Fixtures anhand ihrer Referenz in der YML-Datei zu erhalten, wenn Sie nach einem bestimmten Datensatz suchen müssen.


Da die Frage ist, um das Bündel Alice Armaturen, fand ich für mich die folgenden arbeiten:

protected $idGeneratorTypes = []; 

protected function allowFixedIdsFor(array $entityClasses) 
{ 
    $em = $this->getContainer()->get('doctrine')->getManager(); 
    foreach ($entityClasses as $entityClass) { 
     $metadata = $em->getClassMetadata($entityClass); 
     $this->idGeneratorTypes[$entityClass] = $metadata->generatorType; 
     $metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE); 
    } 
} 

protected function recoverIdGenerators() 
{ 
    $em = $this->getContainer()->get('doctrine')->getManager(); 
    foreach ($this->idGeneratorTypes as $entityClass => $idGeneratorType) { 
     $metadata = $em->getClassMetadata($entityClass); 
     $metadata->setIdGeneratorType($idGeneratorType); 
    } 
} 

dann in dem setUp Test() Methode habe ich

$this->allowFixedIdsFor([ 
     MyEntity::class, 
    ]); 


    $this->loadFixtureFiles([ 
     './tests/DataFixtures/ORM/my_entities.yml', 
    ]); 

    $this->recoverIdGenerators(); 

Es sieht so aus, als ob Sie keine setId() Methode in Ihrer Entität haben müssen.

5

Ich lief auch in dieses Problem, da ich wollte, dass einige IDs die gleichen sind, jeden Lauf, da ich sie in meinen Debug-Apps mit der UUID-Strategie verweisen möchte.

Was ich getan habe:

1) einen Befehl schrieb, dass hautelook:fixtures:load wickelt:

protected function execute(InputInterface $input, OutputInterface $output) 
{ 
    $container  = $this->getContainer(); 
    $entityManager = $container->get('doctrine.orm.default_entity_manager'); 

    $metadata = $entityManager->getClassMetaData(App::class); 
    $metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE); 
    $metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator()); 

    $application = new Application($kernel); 
    $application->setAutoExit(false); 

    $this->loadFixtures($application, $output); 
} 

Haben die $metadata -stuff für alle Klassen möchten Sie benutzerdefinierte IDs haben (App::class).

protected function loadFixtures(Application $application, OutputInterface $output) 
{ 
    $loadFixturesInput = new ArrayInput(array(
     'command' => 'hautelook:fixtures:load', 
     '--no-interaction' => 'true', 
     '--verbose' => '3' 
    )); 

    $application->run($loadFixturesInput, $output); 
} 

2) habe ich eine Vorlage die id wie Lehre würde zu erzeugen.

id (template): 
    id (unique): '<uuid()>' 

3) In meiner benutzerdefinierten Entität Befestigung, jetzt kann ich folgendes tun:

app_custom (extends id): 
    id: 'whatever-i-want' 
    title: 'My custom entity' 

4) Und wenn ich will nicht eine benutzerdefinierte ID verwenden, ich ziehe nur‘ t überschreiben die id Feld:

app_another (extends id): 
    title: 'Just another app with an id I do not care about' 

Beweis:

enter image description here

Verwandte Themen