我有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;
//[...]
}
如您所见,这是一对多,单向连接表关联。 Box可以“存储”糖果,但Candy对Box(在哪里)一无所知。
现在我有一个页面,我可以制作糖果,并且有表格和标准isValid()
,之后:
$box->addCandy($candy);
$entity_manager->persist($candy);
$entity_manager->persist($box);
$entity_manager->flush();
现在,我的问题出在哪里了?
我想Box可以存储唯一独特的糖果(通过名称),这意味着Box可以存储名为“Choco”和“Orange”的Candy对象“但不能”蛋黄酱“和”蛋黄酱“
制作糖果时我不能用UniqueEntity
约束验证,因为糖果不知道盒子。我想过Box的Callback
验证器或创建自己的约束,但我认为最好问:
我该怎么做?
答案 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
约束。