Symfony2针对多个字段的唯一验证

时间:2013-10-21 01:51:57

标签: symfony

我有两个字段,希望对它们两者进行独特的验证。 含义namecity组合应该是唯一的。但验证仅针对name

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

1 个答案:

答案 0 :(得分:1)

您必须编写一个回调验证来完成此操作。回调方法将检查给定的城市和名称组合是否存在任何现有位置,如果存在任何位置,则会抛出表单错误。在这个例子中。您必须在实体内调用实体经理。因此,服务容器与bundle一起传递,然后被调用。

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

}