Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 Doctrine2 UniqueEntity validation specifying a value

I already use UniqueEntity in fashion like:

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

So I already know how to use it.

What I need to do in another context is the following:

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

But I need to specify that for the same entityId I cannot have a duplicate if status == 1, but if status == 0 it should pass the validation.

Basically, for example, I can have any number of records with entityId = 37 and status = 0, but only one with status = 1.

Is this possible?

EDIT: Please find here the updated version of it, for double checking. In my original question I forgot to mention another parameter (entityName) but it does not change the essence of it.

Repository class

<?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 [];
}
}

Main class:

<?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
}
like image 586
Sergio Negri Avatar asked Jun 05 '26 07:06

Sergio Negri


1 Answers

You can add repositoryMethod option to UniqueEntity constraint annotation.

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

And implement repository method to find entities by defined criteria.

/**
 * @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 [];
}
like image 59
Mikhail Prosalov Avatar answered Jun 07 '26 23:06

Mikhail Prosalov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!