2

我有 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”但不能存储“蛋黄酱”和“蛋黄酱”的糖果对象

制作糖果时,我无法进行UniqueEntity约束验证,因为糖果不知道盒子的存在。我考虑过CallbackBox 的验证器或创建自己的约束,但我认为最好问:

我该怎么做?

4

1 回答 1

0

答案很晚,但它可能对某人有所帮助,所以这是我实施的解决方案:

就我而言,我Candy只能通过表单在一个地方创建,所以最后我决定在我的控制器/服务中为这种情况创建额外的特殊验证。

简单地说,我以自己的方式编写了代码检查名称,当它无效时,表格只是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约束。

于 2018-02-23T18:19:17.350 回答