2015-12-30 2 views
2

У меня 2 отображенные объекты,Validate UniqueEntity для One-To-Many, однонаправленный с Join Table [Symfony2]

Box

class Box{ 
    //[...] 
    /** 
    * @ORM\ManyToMany(targetEntity="Candy", cascade={"remove"}) 
    * @ORM\OrderBy({"power" = "DESC"}) 
    * @ORM\JoinTable(name="box_candies", 
    *  joinColumns={@ORM\JoinColumn(name="box_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@ORM\JoinColumn(name="candy_id", referencedColumnName="id", unique=true)} 
    *  ) 
    */ 
    private $candies; 
} 

и конфеты

class Candy 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

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

, как вы может видеть, это Один-ко-многим, однонаправленный с объединением таблицы ассоциации. Box может «хранить» конфеты, но Candy ничего не знает о Box (где есть).

Теперь у меня есть страница, где я могу сделать конфеты и есть форма и стандарт isValid() и после этого:

$box->addCandy($candy); 
$entity_manager->persist($candy); 
$entity_manager->persist($box); 
$entity_manager->flush(); 

Теперь, где моя проблема?

Я хотел бы Box можно хранить только уникальные конфеты (по имени), это означает, что ячейка может хранить конфеты объекты с именами «Choco» и «Orange», но не может «Майонез» и «майонез»

При изготовлении конфет я не могу подтвердить с помощью UniqueEntity ограничение, потому что конфеты не знают о коробке. Я думал о Callback валидаторе для коробки или создать собственное ограничение, но я думаю, что лучше спросить:

Как мне это сделать?

+0

См. [Это сообщение] (http://stackoverflow.com/a/18894942/1307183) - вы должны поместить 'UniqueEntity' в поле' name' вашего объекта Candy. Когда вы делаете аннотацию '@ ManyToMany' в своем ядре, Doctrine автоматически обрабатывает это как составной первичный ключ для вас и обеспечивает уникальность именно так, как вы хотите. –

+0

Нет, в моем случае 'name' не является уникальным значением – Griva

+0

Почему это не уникальное значение? –

ответ

0

Ответ поздно, но это может помочь кому-то, так что это решение я реализовал:

В моем случае я могу создать Candy только в одном месте через форму так, в конце концов я решил создать дополнительную специальную проверку для этого случая в мой контроллер/сервис.

Проще говоря, я сделал код, проверяя имя по-своему, и когда он недействителен, сформируйте только trow Error, чтобы предотвратить создание. Я хочу подчеркнуть, что это небольшое грязное решение, а также оно не является масштабируемым, потому что вы должны всегда помнить, чтобы добавить его в правильное место, если вы создаете Candy в других местах.

// special unique name validation 
    $candy_name = $form->get('name')->getData(); 
    if($candy_name){ 
     $found_candy = $box->getCandyByName($candy_name); 
     if($found_candy){ 
      $error = new FormError($this->get('translator')->trans("candy.name.exist", array(), "validators")); 
      $form->get('name')->addError($error); 
     } 
    } 

Во всяком случае он работал, но в зависимости от вашего случая, Callback может быть лучше, решением или даже простое UniqueEntity ограничения.

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