如何防止arraycollection中的重复值?

时间:2017-07-16 16:41:13

标签: symfony doctrine symfony-forms

我有一个Session实体,它具有整数$num属性。两个或多个会话可以具有相同的$num值。 Session可能属于多个Group个实体。

Group也可以附加几个会话。创建Group时,用户可以将其包含的会话分配到ArrayCollection,但是一个群组不能有两个具有相同$num值的会话。

如何使用Symfony Form组件强制执行此限制,特别是使用CollectionType字段类型?

编辑:

这里是从组到会话的(单向)多对多映射:

# Group.orm.yml
manyToMany:
    sessions:
        targetEntity: Session
        joinTable:
            name: sessiongroups_sessions
            joinColumns:
                group_id:
                    referencedColumnName: id
            inverseJoinColumns:        
                session_num:
                    referencedColumnName: num

我将$num设置为inverseJoinColumn中的引用列(而不是id),因此sessiongroups_sessions表永远不会有两行或更多行具有相同的组ID引用具有相同$num值的会话。

从数据库的角度来看这很好(编辑:显然不是,我认为这可以在不尝试的情况下工作),我需要知道如何在表单中强制执行此操作/ strong>用户指定组的会话。

我知道有一个名为Collection的约束,但它需要为集合的每个键指定一个验证器。我知道我可以构建表单来向集合添加会话,如下所示:

$group = new Group();
$form = $this->createFormBuilder($group)->add('sessions', CollectionType::class,
array('entry_type' => EntityType::class, 'entry_options' => array('class' => AppBundle:Group));

如何在此处指定一个约束,以确保集合永远不会包含两个具有相同$num值的会话?

1 个答案:

答案 0 :(得分:0)

您需要和indexed association

假设您正在使用yaml映射,Group实体中的关联可能如下所示:

  manyToMany:
    sessions:
      targetEntity: Session
      mappedBy: groups
      indexBy: num

然后您需要修改您的setter以使用$num作为键。更多信息,请参阅上述链接中的Doctrine Documentation。

显然,当有人试图根据您的需要添加Session现有$num值时,您还需要处理案例。

@edit:

  

我将$ num设置为inverseJoinColumn中的引用列,(...)从数据库角度看这很好

不,不是。 $num Session实体在$num实体中并不唯一,因此在Group实体中具有Session值,您无法识别任何特定的{{1}}实例。它需要是一个独特的钥匙。