Доктрина 2.1 — Изменение отображения поля (атрибута сущности) на лету

#php #doctrine-orm

#php #doctrine-orm

Вопрос:

Безопасно ли изменять имя столбца базы данных «на лету» в отображении Doctrine в начальной загрузке приложения на случай, если я сделаю это для всех созданных менеджеров сущностей?

 <?php
// In "every second" view sort by score2 instead of by score1 
if (rand(0, 1) % 2 === 0) {
   $entityManager->getMetadataFactory()->getMetadataFor('Advertisement')->fieldMappings['score']['columnName'] = 'score2';
}
  

Атрибут Score используется для сортировки отображаемых объектов, и я хотел бы провести A / B тестирование сортировки по разным столбцам базы данных самым простым способом.

Ответ №1:

Хорошо, кажется, у меня есть решение.

Вероятно, лучший способ — создать собственный ClassMetadataFactory, который расширен из DoctrineORMMappingClassMetadataFactory и создать EntityManagers с этим ClassMetadataFactory .

 <?php
/**
 * Implementation of Doctrine's metadata factory class for A/B testing
 */
class ClassMetadataFactory extends DoctrineORMMappingClassMetadataFactory
{
    /**
     * Gets the class metadata descriptor for a class.
     *  
     * @param string $className The name of the class.
     * @return DoctrineORMMappingClassMetadata
     */
    public function getMetadataFor($className)
    {
        $metadata = parent::getMetadataFor($className);

        if ($className === 'Advertisement' || $className === 'Advertisement') {
            $metadata->fieldMappings['score']['columnName'] = 'score2';
            $metadata->fieldNames['score'] = 'score2';
            $metadata->columnNames['score'] = 'score2';
        }

        return $metadata;
    }
}
  

Еще одна вещь, о которой вы должны знать, — это кэш DQL Doctrine!

Это относительно глупый пример. Следующим шагом может быть настройка A / B-тестирования и некоторого переключателя, отвечающего за решение варианта, но это не относится к теме моего вопроса выше.