2016-04-29 9 views
7

Я использую Symfony2 с Доктриной, и я использую пакет Alice Fixture для создания своих светильников для тестирования.Могу ли я переопределить идентификатор автоматического увеличения с помощью Alice Fixtures?

В одном случае мне нужно создать прибор, где идентификатор - 148 для конкретного теста. Все наши идентификаторы настроены на auto_increment, поэтому я в настоящее время создаю 147 фиктивных записей, чтобы создать тот, который мне нужен.

Я надеялся использовать это определение, чтобы заставить идентификатор должен быть установлен на 148:

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

К сожалению, это не работает. Из поиска Google я прочитал краткий комментарий о том, что мне сначала нужно добавить метод setId для моего объекта. Я пробовал это, но это не имело значения. На самом деле я не хочу добавлять метод setId, если мне это не нужно, поскольку это нарушает наши правила целостности, где мы никогда не разрешаем установку id.

Возможно, существует класс отражения, который можно использовать? Возможно, это встроено в Алису, и я не знаю об этом?

+0

* Сначала мне нужно добавить метод setId для моего объекта. Я пробовал это, но это не имело значения. * Пожалуйста, объясните это более точно, вы получили сообщение об ошибке? Добавление 'setId', вероятно, является лучшим и простым решением вашей проблемы. –

+0

Тип генератора идентификаторов будет переопределять то, что вы установили с помощью setId, поэтому просто установить его на объект не будет трюк. – David

+0

@ Давид Вы уверены? IIRC, auto incrementing используется только тогда, когда первичный идентификатор равен null. –

ответ

6

Если вы хотите, чтобы доктрина сохранила определенное значение для идентификатора автоматического инкремента, вы должны деактивировать автоматическое увеличение в метаданных доктрины. См

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

Другими словами, можем ли мы сказать, что этот код необходим для вызова функции 'setId()'? –

+1

Нет, вы можете вызвать setId также без этого кода, но доктрина просто проигнорирует ваше значение id и по-прежнему будет использовать значение автоматического увеличения. –

+0

Спасибо, вот что я думал, мое предложение было плохо сформулировано. –

5

UPDATE: После дальнейших исследований по данной теме, я понял, что жестко прописывать идентификаторы в светильниках идет со своими собственными проблемами и, как правило, не является хорошей идеей. Вместо этого лучше получить привязки по их ссылке в yml-файле, когда вам нужно проверить конкретную запись.


Поскольку речь идет о светильниках пачке Алиса, я нашел следующий работать для меня:

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); 
    } 
} 

Затем в нАлАдкИ в тесте (в) метода, у меня есть

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


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

    $this->recoverIdGenerators(); 

Похоже, что вам не нужен метод setId() в вашей организации.

5

Я также столкнулся с этой проблемой, так как я хотел, чтобы некоторые идентификаторы были одинаковыми для каждого запуска, так как я хочу ссылаться на них в своих отладочных приложениях, используя стратегию UUID.

То, что я сделал:

1) Написала команду, которая оборачивает hautelook:fixtures:load:

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); 
} 

Сделайте $metadata -stuff для всех классов, которые вы хотите иметь пользовательские идентификаторы (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) Я создал шаблон для генерации id как доктрины будет.

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

3) В моей пользовательской сущности арматуре, теперь я могу сделать следующее:

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

4) И если я не хочу использовать пользовательский идентификатор, я просто не» т перезапись id поле:

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

Доказательство:

enter image description here

 Смежные вопросы

  • Нет связанных вопросов^_^