2014-02-09 52 views
1

最好的做法是检查实体字段在存在之前是否存在。 这里的例子 实体最佳实践 - 检查实体是否在presist之前存在

class Pile{ 
    /** 
    * @var \ABC\CoreBundle\Entity\Record 
    * 
    * @ORM\OneToMany(targetEntity="Record") 
    * 
    */ 
    private $records; 

    /** 
    * @var \CSC\CoreBundle\Entity\Project 
    * 
    * @ORM\ManyToOne(targetEntity="Project") 
    * 
    */ 
    private $project; 

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

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

} 

class Record{ 
    /** 
    * @var \CSC\CoreBundle\Entity\Pile 
    * 
    * @ORM\ManyToOne(targetEntity="Pile") 
    * 
    */ 
    private $records; 
} 

有两个控制器,处理桩和记录的CRUD。 要创建桩,不得有任何重复的字段[项目,块,类型]

在记录控制器中,我可以创建桩与记录。

下面是我在何时以及何时检查分贝是否创建了类似桩实体的问题? 什么是最佳实践?

  1. 将查询检查器复制并粘贴到两个控制器中?
  2. 我可以使用$ form-> valid()在PileType类中执行任何检查吗?
  3. 我必须使用服务并让两个控制器调用服务吗?
  4. 实体生命周期中使用预插入?

感谢

回答

3

您可以在表单中使用自定义验证约束,使$form->isValid()会做检查。 请按照How to create a Custom Validation Constraint上的文档条目创建自定义验证器,然后向其中注入原则以进行检查。

更新:嗯,我不知道有一个UniqueEntity约束已经包含在Symfony中。

要注入学说执行以下操作:然后

services: 
    validator.unique.unique_pile: 
     class: ABC\CoreBundle\Validator\Constraints\UniquePileValidator 
     arguments: [@doctrine.orm.entity_manager] 
     tags: 
      - { name: validator.constraint_validator, alias: unique_pile } 

Validator类可能是这样的:

// src/ABC/CoreBundle/Validator/Constraints/UniquePileValidator.php 
namespace ABC\CoreBundle\Validator\Constraints; 

use Symfony\Component\Validator\Constraint; 
use Symfony\Component\Validator\ConstraintValidator; 

class UniquePileValidator extends ConstraintValidator 
{ 
    protected $em; 

    function __construct($em) { 
     $this->em = $em; 
    } 

    public function validate($value, Constraint $constraint) 
    { 
     $repo = $this->em->getRepository('ABC\CoreBundle\Entity\Record'); 

     $duplicate_project = $repo->findByProject($value); 
     $duplicate_block = $repo->findByBlock($value); 
     $duplicate_type = $repo->findByType($value); 

     if ($duplicate_project || $duplicate_block || $duplicate_type) { 
      $this->context->addViolation(
       $constraint->message, 
       array('%string%' => $value) 
      ); 
     } 
    } 
} 

而且是完整的,约束类:

// src/ABC/CoreBundle/Validator/Constraints/ContainsAlphanumeric.php 
namespace ABC\CoreBundle\Validator\Constraints; 

use Symfony\Component\Validator\Constraint; 

/** 
* @Annotation 
*/ 
class ContainsAlphanumeric extends Constraint 
{ 
    public $message = 'This Pile already exists!'; 

    public function validatedBy() 
    { 
     return 'unique_pile'; 
    } 
} 

应该近似复制/粘贴...

3

因此,这些字段必须是唯一的?

如果是这样的话,那是很简单的:UniqueEntity

use Symfony\Component\Validator\Constraints as Assert; 
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; 
... 

/** 
* @ORM\Entity 
* @UniqueEntity(
*  fields={"project", "block", "type"} 
*) 
*/ 
class Pile{ 
    /** 
    * @var \ABC\CoreBundle\Entity\Record 
    * 
    * @ORM\OneToMany(targetEntity="Record") 
    * 
    */ 
    private $records; 

    /** 
    * @var \CSC\CoreBundle\Entity\Project 
    * 
    * @ORM\ManyToOne(targetEntity="Project") 
    * 
    */ 
    private $project; 

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

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

}