Проверка уникальности для однонаправленного соединения «один ко многим» с таблицей соединений [Symfony2]

У меня есть 2 сопоставленных объекта,

коробка

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

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

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

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

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

Я хотел бы, чтобы коробка могла хранить только уникальные конфеты название), это означает, что Box может хранить объекты Candy с именами «Чоко» и «Апельсин» но не могу «Майонез» и «Майонез»

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

Как я должен это делать?

2

Решение

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

В моем случае я могу создать 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);
}
}

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

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]