问题描述
我有 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(它在哪里)一无所知.
As you can see, this is One-To-Many, Unidirectional with Join Table association. Box can "store" candies, but Candy knows nothing about Box (where is).
现在我有了可以制作糖果的页面,并且有表格和标准的isValid()
,然后是:
Now I have page where I can make candy and there is form and standard isValid()
and after that:
$box->addCandy($candy);
$entity_manager->persist($candy);
$entity_manager->persist($box);
$entity_manager->flush();
现在,我的问题在哪里?
我希望 Box 可以存储仅独特的糖果(按名称),这意味着 Box 可以存储名为 Choco"和Orange"的 Candy 对象" 但不能蛋黄酱"和蛋黄酱"
I would like to Box can store only unique candies (by name), that means Box can store Candy objects with names "Choco" and "Orange" but can't "Mayonnaise" and "Mayonnaise"
制作糖果时,我无法使用 UniqueEntity
约束进行验证,因为糖果不知道盒子.我想过 Box 的 Callback
验证器或创建自己的约束,但我认为最好问:
When making candy i can't validate with UniqueEntity
constraint because the candy does not know about the box. I thought about Callback
validator for Box or create own Constraint but i think it's better to ask:
我该怎么做?
推荐答案
回答晚了,但它可能对某人有帮助,所以这是我实施的解决方案:
Answer is late but it may help someone so this is solution I implemented:
在我的情况下,我只能通过表单在一个地方创建 Candy
所以最后我决定在我的控制器/服务中为这种情况创建额外的特殊验证.
In my case I can create Candy
only in one place via form so finally I decided to create additional special validation for that case in my controller/service.
简单地说,我用我自己的方式编写了代码检查名称,当它无效时,就形成 Error
以防止创建.我想强调的是,这是一个有点肮脏的解决方案,而且它不可扩展,因为如果您在其他地方创建 Candy,您必须记住始终将其添加到正确的位置.
Simply speaking I made code checking the name in my own way and when it's invalid, form just trow Error
to prevent creation. I want to emphasize that this is a little dirty solution and also it is not scalable because you have to remember always to add it in correct place if you create Candy in other places.
// 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
约束.
Anyway it worked but depending on your case, Callback can be way better solution or even simple UniqueEntity
constraint.
这篇关于使用连接表验证一对多单向的 UniqueEntity [Symfony2]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!