2015-02-23 40 views
0

我有一个学说与这两列实体Cart学说防止特定值对相同两列

  • $user(一个多对一柱引用到用户实体)
  • $status(字符串字段与两个可能的值:pendingcompleted

...和我必须防止两个“待定”车为同一用户

我该怎么做?

UniqueConstraint不是解决方案,因为用户必须能够拥有两个或更多完成的购物车,但只有一个待处理的购物车。

在另一方面,我可以实现一个prePersist监听器,并插入之前检查重复的值,但因为我不想做额外查询数据库我不喜欢这样的解决方案。

任何解决方案?

+1

止跌在创建新的产品之前,更容易检查用户是否已经拥有待定购物车? – 2015-02-23 12:14:30

+1

也这么认为,添加一个方法hasPending()检查,如果(!$ e-> hasPending()){add()} – 2015-02-23 12:18:32

+0

@Daniel和约翰,也许是最好的解决方案,谢谢。我的用户有一个方法getCurrentCart(),我在过滤“待处理”购物车,我可以检查$ user-> hasCurrentCart(),然后创建一个新的。谢谢。 – xhostar 2015-02-23 14:08:27

回答

1

最后,以下的建议和Symfony documentation我选择了这个解决方案:

约束类

<?php 
namespace MyBundle\Validator\Constraints; 
use Symfony\Component\Validator\Constraint; 

/** 
* @Annotation 
* 
*/ 
class UniquePendingCart extends Constraint 
{ 
    public $message = 'Only one pending cart by user'; 

    public function getTargets() 
    { 
     return self::CLASS_CONSTRAINT; 
    } 

    public function validatedBy() 
    { 
     return 'my.validator.unique_pending_cart'; 
    } 
} 

验证服务 注入我CartRepository服务:

my.validator: 
    class: AppBundle\Validator\Constraints\UniquePendingCartValidator 
    arguments: 
     - @my.cart_repository 
    tags: 
     - name: validator.constraint_validator 
     - alias: my.validator.unique_pending_cart 

约束验证

<?php 
namespace MyBundle\Validator\Constraints; 
use Doctrine\Common\Persistence\ObjectRepository; 
use Symfony\Component\PropertyAccess\PropertyAccess; 
use Symfony\Component\Validator\Constraint; 
use Symfony\Component\Validator\ConstraintValidator; 
use Symfony\Component\Validator\Exception\UnexpectedTypeException; 

use Bshop\AppBundle\Model\Interfaces\OrderInterface; 

class UniquePendingCartValidator extends ConstraintValidator 
{ 
    protected $repository; 

    public function __construct(ObjectRepository $repository) 
    { 
     $this->repository = $repository; 
    } 

    public function validate($value, Constraint $constraint) 
    { 
     if (!$constraint instanceof UniquePendingCart) { 
      throw new UnexpectedTypeException($constraint, 
       __NAMESPACE__.'\UniquePendingCart'); 
     } 

     $isValid = $this->isStatusValid($value); 

     if (!$isValid) { 
      $this->context->buildViolation($constraint->message) 
       ->addViolation(); 
     } 
    } 

    protected function isStatusValid($cart) 
    { 
     // use repository to find another possible pending cart 
     return true; 
    } 
} 

然后在我的Cart实体申请约束现在

<?php 
use Doctrine\ORM\Mapping as ORM; 
use MyBundle\Validator\Constraints as MyAssert; 

/** 
* @ORM\Entity 
* @MyAssert\UniquePendingCart 
*/ 
class Cart { 
    // ... 
} 

,我可以验证$车,并验证是否有效?

$cart = // my cart 

$validator = $this->get("validator"); 
$errors = $validator->validate($cart); 

if (0 !== count($errors)) { 
    // ops, exception... 
} 
+0

这就是我在评论中的意思:p它需要一点努力,但方式更加灵活。它也尊重实体的目的:) – 2015-02-25 13:55:17