2014-01-17 4 views
0

У меня есть сущность, но я хочу проверить максимум X записей в db. Например, допустимо не более 5 категорий в БД. Я пытаюсь проверить, не решена ли какая-либо проверка правильности моей проблемы, но я не нахожу ничего полезного. Заранее благодаренМаксимальное количество записей

ответ

0

Если вам необходимо проверить свою сущность в нескольких местах или выполнить этот тип проверки для более чем одного класса сущностей, вы можете написать специальное ограничение проверки для этого. Это немного похоже на перебор, но это технически «правильное» решение. Это описано в Руководстве по Symfony в How to create a Custom Validation Constraint. Например:

Constraint класс:

<?php 

namespace Your\Bundle\Validator\Constraints; 

use Symfony\Component\Validator\Constraint; 

class MaxEntries extends Constraint 
{ 
    public $message = 'The maximum %max% %name% entries already exist.'; 
    public $max = 5; 

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

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

ConstraintValidator класс:

<?php 

namespace Your\Bundle\Validator\Constraints; 

use Doctrine\ORM\EntityManager; 

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

class MaxEntriesValidator extends ConstraintValidator 
{ 
    private $entityManager; 

    public function __construct(EntityManager $entityManager) 
    { 
     $this->entityManager = $entityManager; 
    } 

    public function validate($protocol, Constraint $constraint) 
    { 
     /** @var MaxEntries $constraint */ 

     $protocolClass = new \ReflectionClass(get_class($protocol)); 
     $entityName = $protocolClass->getShortName(); 
     // alternative to next 2 lines - you could use dql to do a select count 
     $repository = $this->entityManager->getRepository('YourBundle:' . $entityName); 
     $entities = $repository->findAll(); 

     if (count($entities) == $constraint->max) 
     { 
      $this->context->addViolation($constraint->message, array(
       '%max%' => $constraint->max, 
       '%name%' => $entityName, 
      )); 
     } 
    } 
} 

services.yml:

validator.max_entries: 
    class: Bullitt\TargetNeutral\SpectatorBundle\Validator\Constraints\MaxEntriesValidator 
    arguments: [@doctrine.orm.entity_manager] 
    tags: 
     - { name: validator.constraint_validator, alias: maxEntries } 

validation.yml:

Your\Bundle\YourEntity: 
    constraints: 
     - Your\Bundle\Validator\Constraints\MaxEntries: 
      # You can override the default constraint attributes here 
      message: "Failed! The maximum %max% %name% entries already exist." 
      max: 42 

Обратите внимание: возможно, вам удастся придумать лучшее имя, чем MaxEntries (я обычно трачу больше времени на размышления о наиболее значимом имени). Кроме того, класс validator в настоящее время не содержит защиты для применения к классу, который не является объектом доктрины.

+0

Идеально, это то, что я искал. Я еще не тестировал его, но спасибо! – Oriam

0

Возможно, вам придется реализовать это самостоятельно. Я такого не видел, но было бы непросто сделать что-то свое. Просто добавьте функцию, чтобы проверить, сколько записей у вас есть в db, и вызовите эту функцию, прежде чем вставлять что-либо.

Нечто подобное можно сделать:

public function newAction(){ 
    $isAllowed = $this->checkMaxRecords(); 

    if($isAllowed){ 
     //save to the database 
    } 
} 

private function checkMaxRecords(){ 
    $em = $this->getDoctrine()->getManager(); 
    $query = $em->createQuery(
     'SELECT c 
     FROM AcmeStoreBundle:Category c' 
    ); 

    $category = $query->getResult(); 

    if(count($category) >= 5){ 
     return false; 
    } 
    return true; 
} 

Это непроверенный код, но что-то вдоль этих линий должны вы на правильном пути.

+0

Спасибо, но это не то, что я хочу сделать. Я думал прямо в ограничении проверки. Я даже не задумываюсь в слушателе доктрины для prepersist :(Может быть, решение с использованием проверки обратного вызова (@Assert \ Callback) ... – Oriam

Смежные вопросы