Несколько аннотаций @UniqueEntity на одном объекте

У меня есть сущность, которая имеет два уникальных индекса. Мне нравится добавлять два UniqueEntity ограничения для объекта для целей проверки.

Данная сущность:

/**
* @ORM\Entity
* @ORM\Table(name="sample", uniqueConstraints={
*     @ORM\UniqueConstraint(columns={"user_id", "hash"}),
*     @ORM\UniqueConstraint(columns={"user_id", "name"})
* })
* @UniqueEntity(fields={"user", "jobSearch"}, message="duplicate_hash")
* @UniqueEntity(fields={"user", "name"}, message="duplicate_name")
*/
class SampleEntity
{
// ...
}

Проблема: только последняя @UniqueEntity получает уважение. Так что только дубликат ключа для user а также name признается или наоборот только для user а также jobSearch если я переключу аннотации UniqueEntity.

Есть ли решение для покрытия двух уникальных индексов @UniqueEntity?

1

Решение

Я обошел это с помощью пользовательской проверки. Образец кода;
в SRC / AppBundle / Validator / Ограничения

<?php
// src/AppBundle/Validator/Constraints/UniqueCodeName.php
namespace AppBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;

/**
* @Annotation
*/
class UniqueCodeName extends Constraint
{
public $message = "must have a unique code and name.";

public function validatedBy()
{
return 'code_name';
}
}

А также

<?php
// src/AppBundle/Validator/Constraints/UniqueCodeName.php
namespace AppBundle\Validator\Constraints;

use Doctrine\ORM\EntityManager;

use Symfony\Component\Validator\Constraint,
Symfony\Component\Validator\ConstraintValidator;

/**
* @Annotation
*/
class UniqueCodeNameValidator extends ConstraintValidator
{
private $entityManager;

public function __construct(EntityManager $em)
{
$this->entityManager = $em;
}

public function validate($value, Constraint $constraint)
{
$formCampaign = $this->context->getRoot()->getData();
$code_name = $formCampaign->getClient()->getCode().$formCampaign->getCode();
$campaigns = $this->entityManager->getRepository('AppBundle:Campaign')->findBy(
[
'code' => $code_name,
'name' => $formCampaign->getName()
]
);

if ($campaigns) {
$this->context->buildViolation($constraint->message)
->addViolation();
}
}
}

Сервисная декларация для ограничения;

services:
validator.unique.campaign_code_name:
class: AppBundle\Validator\Constraints\UniqueCodeNameValidator
tags:
- { name: validator.constraint_validator, alias: code_name }
arguments: ["@doctrine.orm.entity_manager"]

Образец класса сущности;

<?php // src/AppBundle/Enitiy/Campaign.php
namespace AppBundle\Entity;
use AppBundle\Validator\Constraints as AppAssert;
use Doctrine\ORM\Mapping as ORM,
Doctrine\Common\Collections\ArrayCollection;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity,
Symfony\Component\Validator\Constraints as Assert;
use \DateTime;

/**
* Campaign
*
* @ORM\Table(name="campaign")
* @ORM\Entity(repositoryClass="AppBundle\Entity\CampaignRepository")
* @UniqueEntity(fields={"code", "name"})
*/
class Campaign
{
// other stuff

/**
* @var string
*
* @ORM\Column(name="code", type="string", length=255, unique=true)
*/
private $code;

/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255, unique=true)
*/
private $name;

/**
* Get code
*
* @Assert\Length(min=2, max=11, groups={"create", "update"})
* @Assert\Regex(pattern="/\d/", match=true, message="Code must be numeric", groups={"create", "update"})
* @Assert\NotBlank(groups={"create", "update"})
* @AppAssert\UniqueCodeName(groups={"create", "update"})
* @return string
*/
public function getCode()
{
return $this->code;
}
}
2

Другие решения

У меня была идея создать ChainValidator который может держать N другие валидаторы:

/**
* @ORM\Entity
* @ORM\Table(name="sample", uniqueConstraints={
*     @ORM\UniqueConstraint(columns={"user_id", "hash"}),
*     @ORM\UniqueConstraint(columns={"user_id", "name"})
* })
* @Chain(constraints={
*     @UniqueEntity(fields={"user", "hash"}, message="duplicate_hash"),
*     @UniqueEntity(fields={"user", "name"}, message="duplicate_name")
* })
*/
class SampleEntity
{
// ...
}

Таким образом, можно добавить N UniqueEntity валидаторы одной сущности.

Когда я гуглил это, чтобы выяснить, есть ли у кого-то еще эта идея. Я нашел эту суть: https://gist.github.com/rybakit/4705749 что в основном именно то, что мне нужно, и в итоге реализовано очень похожим образом.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector