Symfony2 Doctrine2 UniqueEntity验证指定值

3

我已经以这种方式使用UniqueEntity:

/**
 * @ORM\Entity()
 * @ORM\Table(name="benefit_group_category")
 * @UniqueEntity(fields={"name", "project"}, ignoreNull=false, message="Duplicated group category for this project")
 */

我已经知道如何使用它。

在另一种情况下,我需要做以下操作:

 * @UniqueEntity(fields={"entityId", "status"}, message="There is already a Quality Review Pending for this entity")

但需要指出,对于相同的entityId如果status == 1,则不允许有重复项,但如果status == 0,则应该通过验证。
基本上,例如,我可以有任意数量的记录,其中entityId = 37并且status = 0,但只有一个status = 1
这是可能的吗?
编辑:请在此处找到更新后的版本,以进行二次检查。 在我的原始问题中,我忘记提及另一个参数(entityName),但这并不改变其本质。
存储库类
<?php

namespace AppBundle\Entity;

/**
 * QualityReviewRequestRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class QualityReviewRequestRepository extends \Doctrine\ORM\EntityRepository
{
/**
 * @param array $criteria
 * @return array
 */
public function getByEntityIdAndEntityNameAndStatusCriteria(array $criteria)
{
    // Todo remove this first return, it's done on purpose to force the system to throw an error, but it doesn't.
            return $this->createQueryBuilder('e') 
            ->andWhere('e.entityId = :entityId')
            ->setParameter('entityId', $criteria['entityId'])
            ->getQuery()
            ->getResult()
        ;

    if (QualityReviewRequest::STATUS_NEW == $criteria['status']) {
        return $this->createQueryBuilder('e')
            ->andWhere('e.entityId = :entityId')
            ->setParameter('entityId', $criteria['entityId'])
            ->andWhere('e.entityName = :entityName')
            ->setParameter('entityName', $criteria['entityName'])
            ->andWhere('e.status = :status')
            ->setParameter('status', $criteria['status'])
            ->getQuery()
            ->getResult()
        ;
    }

    return [];
}
}

主类:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Timestampable\Traits\TimestampableEntity;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

/**
 * QualityReviewRequest
 *
 * @ORM\Table(name="quality_review_requests")
 * @ORM\Entity(repositoryClass="AppBundle\Entity\QualityReviewRequestRepository")
 * @UniqueEntity(fields={"entityId","entityName","status"}, repositoryMethod="getByEntityIdAndEntityNameAndStatusCriteria", message="There is already a Quality Review Pending for this entity")
 */
class QualityReviewRequest
{
    const STATUS_NEW = 0;
    const STATUS_DONE = 1;

    use TimestampableEntity;

    // removed useless stuff

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


    /**
     * @var integer
     *
     * @ORM\Column(name="entityId", type="integer")
     */
    private $entityId;

    // More stuff
}
1个回答

5
您可以将repositoryMethod选项添加到UniqueEntity约束注释中,具体请参考文档
* @UniqueEntity(fields={"entityId", "status"}, repositoryMethod="getEntityByIdAndStatusCriteria", message="There is already a Quality Review Pending for this entity")

并实现存储库方法以按定义的条件查找实体。

/**
 * @param array $criteria
 * @return array
 */
public function getEntityByIdAndStatusCriteria(array $criteria)
{
    if (1 == $criteria['status']) {
        return $this->createQueryBuilder('e')
            ->andWhere('e.entityId = :entityId')
            ->setParameter('entityId', $criteria['entityId'])
            ->andWhere('e.status = :status')
            ->setParameter('status', $criteria['status'])
            ->getQuery()
            ->getResult()
        ;
    }

    return [];
}

你的解决方案看起来确实非常有前途,但我一定是犯了某些错误,因为该方法从未被调用。我已经多次检查了语法。我甚至更改了方法名称,使用了存储库中不存在的名称(故意),但它并没有给我任何错误提示。它只是无视我并将记录添加到数据库中 :/ - Sergio Negri
它对我很有效。请确保您的存储库类在@ORM\Entity注释中定义。(@ORM\Entity(repositoryClass="AppBundle\Entity\Repository\EntityRepository")) 并且在定义repositoryMethod之后已清除缓存。此外,请尝试在存储库方法代码中执行“die();”以确保其被正确调用。您的实体中是否有任何验证组? - Mikhail Prosalov
请查看我的更新问题。没有验证组。该方法甚至没有被调用(我编写了一些必须失败的内容,例如 $criteria['inexistentCriteria'],但它从未到达抛出错误的地方)。仓库类已自动生成,因此不应该是问题。我相信这是一个愚蠢的问题。再次感谢您的时间。 - Sergio Negri
忘了提到我用“硬核”方式清除了缓存(删除目录)。 - Sergio Negri
您可以使用Validator服务来验证实体,而无需表单。以下是一个示例:http://symfony.com/doc/current/book/validation.html#using-the-validator-service - Mikhail Prosalov
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接