我想同时验证表的唯一2列。我在2个独立的列上每个客户端有2个电话,如下所示:
/**
* @ORM\Entity(repositoryClass="App\Repository\ClientRepository")
* @ORM\Table(name="client",
* uniqueConstraints={
* @UniqueConstraint(name="phone_second_phone_constraint",
* columns={"phone", "second_phone"})
* })
* @UniqueEntity("email")
* @UniqueEntity("phone")
* @UniqueEntity("second_phone")
*/
class Client {
/**
* @ORM\Column(name="phone", type="phone_number", length=50, unique=true, nullable=true)
* @AssertPhoneNumber(type="any")
*/
protected $phone = null;
/**
* @ORM\Column(name="second_phone", type="phone_number", length=50, unique=true, nullable=true)
* @AssertPhoneNumber(type="any")
*/
protected $second_phone = null;
}
我不想在任何专栏或任何客户端重复使用手机。
有关如何实现这一目标的任何想法吗?
谢谢和亲切的问候, 大卫M。
答案 0 :(得分:1)
因此,如果我理解正确,您需要在phone
或second_phone
中使用电话号码时无法重复使用。
因此,结合这两个字段的唯一键无法帮助您,因为当相同的电话号码出现在相同的确切字段中时,它只会违反唯一约束,例如phone = X和second_phone = Y you将能够保存phone = Y和second_phone = X。
为避免这种情况,您必须创建一个自定义约束,以检查数据库中是否已存在电话号码。
Here是有关如何在symfony中创建和使用约束的文档。
所以你的代码看起来像这样
您的自定义约束
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class UniquePhoneNumber extends Constraint
{
public $message = 'The phone number "{{ phoneNumber }}" is already in use.';
}
您的约束验证程序
use Doctrine\ORM\EntityManager;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class UniquePhoneNumberValidator extends ConstraintValidator
{
private $entityManager;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function validate($phoneNumber, Constraint $constraint)
{
$client = $this->entityManager->getRepository(Client::class)->findByPhoneNumber($phoneNumber);
if (!is_null($client)) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ phoneNumber }}',$phoneNumber)
->addViolation();
}
}
}
您的客户端存储库中的某个地方
public function findByPhoneNumber(string $phoneNumber): ?Client
{
$qb = $this->getEntityManager()->createQueryBuilder('c');
$qb->select('c')
->where('c.phone = :phone OR c.second_phone = :phone')
->setParameter('phone',$phoneNumber)
->setMaxResults(1);
return $qb->getQuery()->getOneOrNullResult();
}
然后在手机和validator
上使用新的second_phone
,关于如何执行此操作here是一个链接,这取决于您放置约束类的位置,但一般来说,必须这样做
use App\Validator\Constraints as CustomAssert;
@CustomAssert\UniquePhoneNumber
请注意,您必须为约束和验证器添加命名空间,如果将约束放在App \ Validator \ Constraints的其他文件夹中,则必须在实体文件中调整use语句