2013-10-21 37 views
0

我有兩個字段,並且希望對他們兩者進行獨特的驗證組合。 含義namecity組合應該是唯一的。但驗證只觸發了nameSymfony2對多個字段的唯一驗證

Entity\Location: 
    constraints: 
     - Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity: 
      fields: [name, city] 
      message: "Location for given City Already Exists" 
+0

如果你嘗試添加在城市領域的errorPath配置選項? 'errorPath:city'參見[docs]中的信息(http://symfony.com/doc/current/reference/constraints/UniqueEntity.html#errorpath) – acrobat

回答

1

你必須寫一個回調確認來完成這一信息。回調方法會檢查是否有城市和名稱,如果給定組合的任何現有的位置存在任何位置,它會拋出一個表單錯誤。在這個例子中。您將不得不打電話給實體內的實體經理。所以,服務容器隨着包被傳遞,然後被調用。

在security.yml

Venom\ExampleBundle\Entity\Location: 
constraints: 
    - Callback: 
     methods: [isUniqueCityAndNameCombination] 

在實體

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

在存儲庫

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; 

}

在捆綁的文件,在這種情況下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; 
} 

}