2012-08-05 59 views
3

我在Symfony 2.0.17-DEV和PHP 5.3.14上使用Doctrine 2.2.2。我遇到了多级联合级联选项的问题。例子很简单,希望这个梦幻般的董事会的人能够帮助我。学说2.2.2,级联不能与多对多关联?

无论如何,Meta超类是与User关系的所有者。相关领域和唯一的构造:

abstract class Meta 
{ 
    /** 
    * @ORM\ManyToMany(targetEntity="User", inversedBy="meta") 
    * @ORM\JoinTable(name="meta_users", 
    *  joinColumns={@ORM\JoinColumn(onDelete="CASCADE")}, 
    *  inverseJoinColumns={@ORM\JoinColumn(onDelete="CASCADE")} 
    *) 
    */ 
    protected $users; 

    public function __construct() 
    { 
     $this->users = new ArrayCollection(); 
    } 

    public function addUser(User $user) 
    { 
     $this->users[] = $user; 
     return $this; 
    } 

    public function getUsers() 
    { 
     return $this->users; 
    } 
} 

(实现,只是空类,是LabelCategory

很简单,它的工作原理,实际上。我的意思是,从元中添加或删除用户实际上会在连接表中添加/删除相应的行。

问题发生在做相反的事情:创建/编辑用户并分配元。 User定义与元联想这种方式,并增加了一个级联=“所有”选项:

class User 
{ 
    /** 
    * @ORM\ManyToMany(targetEntity="Meta", mappedBy="users", cascade={"all"}) 
    */ 
    protected $meta; 

    public function __construct() 
    { 
     $this->meta = new ArrayCollection(); 
    } 

    public function addMeta(Meta $meta) 
    { 
     $this->meta[] = $meta; 
     return $this; 
    } 

    public function getMeta() 
    { 
     return $this->meta; 
    } 
} 

我是很新的学说,但是这是行不通的。在我的Symfony 2的形式,用于创建/编辑User,我已经添加entity类型的字段,只选择所有的元:

$builder 
    ->add('meta', 'entity', array(
     'label'   => 'Meta', 
     'class'   => 'Acme\HelloBundle\Entity\Meta', 
     'property'  => 'select_label', 
     'multiple' => true, 
     'expanded' => true, 
    )) 
; 

任何表没有改变分配(使用复选框)元给用户时。怎么了?我确定我错过了一些东西,但我找不到什么。

回答

1

说出我所知道的。

级联选项与保持连接表关联无关。当在实体User(或删除旧实体)的关系meta中找到新的Meta实体时,应使用它。也就是说,在表单中,添加一些输入以创建新元或删除现有元,例如使用collection作为Symfony 2提供的字段类型)。或者当你这样做时:

$newMeta = new Meta(); 

$user->addMeta($meta); 

$em->persist($user); // A new entity was found in the relation meta 

就我所了解的你想要坚持关系本身; Doctrine 总是寻找拥有方为了坚持实体。意思是从反面你想先坚持用户,比坚持每个元添加或删除用户,如果相应的复选框被选中或没有。

您的字段为entity类型,表示所有元素都从您的表中获取,并且已分配给用户的元素被标记为已选中。

我记得做类似的东西,这里是一个“伪”控制器代码:

$em->persist($user); // Perstist the inverse side 

// This is what user selected 
$selectedMeta = $user->getMeta(); 

// All meta coming from your database 
$allMeta = $em->getRepository('YourBundle::Meta')->find(); 

// Loop on the owning side 
foreach($allMeta as $meta) 
{ 
    // Is current meta selected? 
    $isSelected = $selectedMeta->contains($meta); 

    // Does this meta have already the user in it? 
    $hasUser = $meta->getUsers()->contains($user); 

    // To be removed: not selected and with the user 
    if(!$isSelected && $hasUser) 
     $meta->getUsers()->removeElement($user); 

    // To be added: selected and without the user 
    if($isSelected && !$hasUser) 
     $meta->addUser($user); 

    $em->persist($meta); // Persist the owning side and the association 
} 

// Apply 
$em->flush(); 

等待确认呢!