如何解决类中具有空值的唯一实体集 symfony / api-platform
shape
--------------
?float height
?float width
?float depth
我想将对象的创建限制为唯一值,包括空值的组合 例如:
shape1: 1,1,1
shape2: 1,null,null
shape3: 1,null
shape4: null,null
...
我试图添加一个 UniqueEntity 约束来做到这一点:
* @UniqueEntity(
* fields={"height","width","depth"}
* )
但验证仅在传递实际值时触发:
id height width depth
1 1 1 1 <- triggers constraint if inserted twice
2 1 null null <- does not trigger constraint if inserted twice
3 null null null <- does not trigger constraint if inserted twice
4 1 1 null <- triggers constraint if inserted twice
我该如何解决这个问题?
ignoreNull 将完全忽略空值,或者,如果设置为 =false
,将在第一个空值之后触发,再次完全忽略该字段。
解决方法
您可以尝试创建一个 Class Constraint Validator。其中可能有以下内容:
public function validate($shape,Constraint $constraint)
{
$same = false;
$nulls = is_null($shape->getHeight()) + is_null($shape->getWidth()) + is_null($shape->getDepth());
if ($shape->getHeight() === $shape->getWidth() || $shape->getHeight() === $shape->getDepth() || $shape->getWidth() === $shape->getDepth()) {
$same = true;
}
if ($nulls > 1 || !$same) {
return;
}
$this->context->buildViolation($constraint->message)
->atPath('foo')
->addViolation();
}
然而,这不会测试是否已经存在具有相同尺寸的形状。
,我最终按照@geoB 的建议创建了一个类约束验证器:
<?php
namespace App\Validator\Constraints;
use Doctrine\Common\Persistence\ManagerRegistry;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
// https://symfony.com/doc/current/validation/custom_constraint.html
class RequiresUniqueEntityValidator extends ConstraintValidator
{
/**
* @var ManagerRegistry
*/
private ManagerRegistry $managerRegistry;
public function __construct(
ManagerRegistry $managerRegistry
)
{
$this->managerRegistry = $managerRegistry;
}
public function validate($value,Constraint $constraint)
{
$repository = $this->managerRegistry->getRepository(get_class($value));
$reflection = new \ReflectionClass($value);
$properties = $reflection->getProperties();
$items = [];
foreach ($properties as $property) {
$propertyValue = $value->{"get" . ucfirst($property->name)}();
$items[$property->name] = $propertyValue;
}
$result = $repository->findBy($items);
if (count($result) > 0) {
// if an item was found,that means that it already exists -> raise Violation
}
$text = 'The Item with fields: is not unique';
$this->context
->buildViolation($constraint->message)
->setParameter('{{ notUnique }}',$text)
->atPath(get_class($value))
->addViolation();
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。