Могу ли я переопределить идентификатор автоинкремента с помощью приборов Алисы?
Я использую Symfony2 с Doctrine и использую пакет Alice Fixture для генерации своих приборов для тестирования.
В одном случае мне нужно создать прибор, в котором идентификатор для определенного теста равен 148. Все наши идентификаторы настроены на auto_increment, поэтому в настоящее время я создаю 147 фиктивных записей только для того, чтобы создать ту, которая мне нужна.
Я надеялся использовать это определение, чтобы установить идентификатор 148:
invoiceClassNoClass (extends invoiceClass):
id: 148
sortOrder: 1
label: 'No Class'
К сожалению, это не работает. Из поиска в Google я прочитал краткий комментарий о том, что мне сначала нужно добавить метод setId к моей сущности. Я попробовал это, но это не имело значения. На самом деле я не хочу добавлять метод setId, если он мне не нужен, поскольку он нарушает наши правила целостности, когда мы никогда не разрешаем установку идентификатора.
Возможно, есть класс отражения, который можно использовать? Возможно, это встроено в Алису, и я не знаю об этом?
3 ответа
Если вы хотите, чтобы доктрина сохранила определенное значение для идентификатора автоинкремента, то вы должны деактивировать автоинкремент в метаданных доктрины. Увидеть
Явно установите Id с Doctrine при использовании стратегии "AUTO"
$this->em->persist($entity);
$metadata = $this->em->getClassMetaData(get_class($entity));
$metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());
ОБНОВЛЕНИЕ: После дальнейших исследований по этому вопросу я понял, что жесткое кодирование идентификаторов в приборах имеет свои проблемы и, как правило, не очень хорошая идея. Вместо этого лучше получить приборы по их ссылке в файле yml, когда вам нужно проверить конкретную запись.
Так как вопрос касается комплекта приборов Alice, я нашел следующее, чтобы работать для меня:
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);
}
}
Затем в методе setUp() теста у меня есть
$this->allowFixedIdsFor([
MyEntity::class,
]);
$this->loadFixtureFiles([
'./tests/DataFixtures/ORM/my_entities.yml',
]);
$this->recoverIdGenerators();
Похоже, вам не нужно иметь метод setId() в вашей сущности.
Я также столкнулся с этой проблемой, так как я хотел, чтобы некоторые идентификаторы были одинаковыми при каждом запуске, так как я хочу ссылаться на них в моих приложениях отладки, используя 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
-материал для всех классов, которые вы хотите иметь собственные идентификаторы (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'
Доказательство: