0

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"
1
  • If you try to add the errorPath config option on the city field? errorPath: city see info in the docs Commented Oct 21, 2013 at 5:20

1 Answer 1

1

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; 
}

}

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.