Reputation: 919
I have two fields and want a unique validation on both of them combined.
Meaning name
and city
combination should be unique. But validation is triggering only for name
Entity\Location:
constraints:
- Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity:
fields: [name, city]
message: "Location for given City Already Exists"
Upvotes: 0
Views: 1513
Reputation: 1327
You will have to write a call back validation to accomplish this.The call back method will check whether there are any existing locations for the given combination of city and name and, if there exist any location, it will throw a form error. In this example. you will have to call the entity manager within the entity. So, the service container is passed along with the bundle and is then called.
In security.yml
Venom\ExampleBundle\Entity\Location:
constraints:
- Callback:
methods: [isUniqueCityAndNameCombination]
In entity
use Symfony\Component\Validator\ExecutionContext;
use Venom\ExampleBundle;
public function isUniqueCityAndNameCombination(ExecutionContext $context)
{
$city = $this->getCity();
$name = $this->getName();
//you will have to call the Entity repository within the entity
$em = ExampleBundle::getContainer()->get('doctrine')->getEntityManager();
$location = $em->getRepository('ExampleBundle:Location')->findByNameAndCity(
$city, $name);
if($location) {
$propertyPath = $context->getPropertyPath() . '.name';
$context->setPropertyPath($propertyPath);
$context->addViolation("Location for given City Already Exists", array(), null);
}
return;
}
In the repository
public function dindByNameAndCity($city, $name)
{
$qb = $this->getEntityManager()->createQueryBuilder();
$em = $this->getEntityManager();
$qb->select('a')
->from('ExampleBundle:Location', 'a')
->andWhere('a.city = :city')
->andWhere('a.name = :name')
->setParameter('city', $city)
->setParameter('name', $name)
;
$q = $qb->getQuery();
$entity = $q->getOneOrNullResult();
return $entity;
}
In the bundle file, in this case ExampleBundle.php
namespace Venom\ExampleBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use \Symfony\Component\DependencyInjection\ContainerInterface;
class ExampleBundle extends Bundle
{
private static $containerInstance = null;
public function setContainer(ContainerInterface $container = null)
{
parent::setContainer($container);
self::$containerInstance = $container;
}
public static function getContainer()
{
return self::$containerInstance;
}
}
Upvotes: 1