Я использую Перечисления Spatie в моем проекте Symfony, и я создал собственный тип DBAL для этих объектов.Когда я сохраняю объект enum в базе данных, я сохраняю его в специальном строковом формате.Функция преобразования в моем EnumType
выглядит следующим образом:
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
if ($value === null) {
return null;
}
return get_class($value) . '::' . $value->getIndex() . '::' . $value->getValue();
}
Так, например, у меня есть перечисление статуса транзакции, которое выглядит так:
namespace App\Enum;
use Spatie\Enum\Enum;
/**
* @method static self failed()
* @method static self pending()
* @method static self completed()
*/
final class TransactionStatus extends Enum {}
И когда я сохраняю его вбазу данных, которую он может превратить в любую из этих строк соответственно:
App\Enum\TransactionStatus::0::failed
App\Enum\TransactionStatus::1::pending
App\Enum\TransactionStatus::2::completed
Это помогает моему EnumType
узнать, во что перечислить, чтобы преобразовать его обратно.И причина, по которой я использую индексный номер в строке, заключается в том, что это помогает с сортировкой.
Теперь все это очень хорошо работает для извлечения и сохранения моих сущностей в базе данных.Но когда я пытаюсь использовать enum в предложении where оператора DQL, он вообще не работает.
namespace App\Repository;
use App\Entity\Transaction;
use App\Enum\TransactionStatus;
use Symfony\Bridge\Doctrine\RegistryInterface;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
class TransactionRepository extends ServiceEntityRepository
{
public function __construct(RegistryInterface $registry)
{
parent::__construct($registry, Transaction::class);
}
public function findByStatus(TransactionStatus $status)
{
return $this->createQueryBuilder('t')
->andWhere('t.status = :status')
->setParameter('status', $status)
->getQuery()->getResult();
}
}
Потому что по какой-то причине доктрина игнорирует мою функцию преобразования и просто использует __toString()
функция, которая встроена в перечисление Spatie.Таким образом, доктрина ищет строку "pending"
вместо "App\Enum\TransactionStatus::1::pending"
.
Как мне убедиться, что мои перечисления всегда правильно конвертируются в предложении DQL where?