2012-02-01 159 views
18

我在多對多關係中遇到了一些麻煩。我有UsersAssets。我希望能夠將用戶分配到資產頁面上的資產。Symfony2 Doctrine2多對多形式不保存實體

下面的代碼顯示創建/編輯資產時的用戶列表,但對用戶複選框所做的更改不會保存,而其餘數據將保留。

如果我通過mysql客戶端向users_assets添加一個條目,這些更改將顯示在資產列表中。

用戶

class User extends BaseUser 
{ 
    /** 
    * @ORM\ManyToMany(targetEntity="Asset", inversedBy="users") 
    */ 
    private $assets; 
} 

資產

class Asset 
{ 
    /** 
    * @ORM\ManyToMany(targetEntity="User", mappedBy="assets") 
    */ 
    private $users; 
} 

AssetType

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $form = $builder 
     ->add('users', null, array(
      'expanded' => true, 
      'multiple' => true 
     )) 
     ->getForm(); 

    return $form; 
} 
+0

你不應該chanage'null'到' EntityType'?你是什​​麼意思由null?! – Trix 2017-05-09 13:51:29

回答

29

出於某種原因,我不得不切換主義映射得到這個工作:

Asset: 
/** 
* @ORM\ManyToMany(targetEntity="Adaptive\UserBundle\Entity\User", inversedBy="assets") 
* @ORM\JoinTable(name="user_assets") 
*/ 
private $users; 

User: 
/** 
* @ORM\ManyToMany(targetEntity="Splash\SiteBundle\Entity\Asset", mappedBy="users") 
*/ 
private $assets; 

現在,當我保存資產它可以節省相關的用戶。我不需要將builder->添加爲實體或集合。我只是將它傳遞null,並且它使用映射信息,以填補在實體信息:

AssetType: 
->add('users', null, array('expanded' => "true", "multiple" => "true")) 

不知道是什麼原因,我需要有inversedBy和資產VS用戶JoinTable信息,但它似乎是工作現在!

感謝您的建議!

+0

我有類似的問題。對其他人的建議:確保你所有的單數/複數都是他們應該是的,如果你的任何一個實體有多個術語的名稱(例如'CoolDude'),你可能會從知道默認的Doctrine假設你的表名只是它的較低版本,例如'cooldude'。如果它實際上是'cool_dude',我想你必須明確地設置它。你可以看到Doctrine文檔中的內容。 http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/association-mapping.html#many-to-many-bidirectional – 2012-03-28 00:10:37

+0

問題是當你想要一個類似的窗體上反面:它不會工作。 – 2012-05-01 08:58:13

+0

解決方案不適合我,我的連接表總是空的! – Fabien 2014-03-25 10:37:52

0

您需要使用 '收集' 呸ld在你的表單中鍵入。

$builder->add('users', 'collection', array(
    'type' => new UserType(), 
    'prototype' => true, 
    'allow_add' => true, 
    'allow_delete' => true 
)); 

您需要首先創建UserType()表格。

這裏是你需要,包括代碼樣本中的所有信息:

http://symfony.com/doc/current/cookbook/form/form_collections.html

http://symfony.com/doc/current/reference/forms/types/collection.html

+0

我認爲通過傳遞null它會認爲這是類型,通過我的教條映射。我有一個類似的設置使用資產的類別,它的效果很好。這是我必須填充類別集合的代碼: - > add('categories',null,array('expanded'=>「true」,「multiple」=>「true」))...我也沒有需要爲資產中的用戶添加crud功能,而我只需要能夠將當前用戶分配給該資產 – 2012-02-01 20:40:43

+1

確實,來自擴展的原則添加了基於元數據的guesser。如果你已經正確定義了ManyToMany關聯,那麼類型猜測者會將你的字段配置爲'collection'。通過*正確*,我的意思是**的所有者**必須是您的情況下的'資產',這就是爲什麼你必須顛倒你的映射。 – Florian 2012-02-02 18:17:06

+0

'EntityType' +'Expanded' +'Multiple'有什麼問題? – Trix 2017-05-09 13:49:06

4

首先,你應該放棄在註釋反斜線前綴(見注意here)。

而且你需要使用實體字段類型:

$builder->add('users', 'entity', array(
    'class' => 'AdaptiveUserBundle:User', 
    'expanded' => true, 
    'multiple' => true, 
    'query_builder' => function(EntityRepository $er) { 
     return $er->createQueryBuilder('u') 
      ->orderBy('u.username', 'ASC'); 
    }, 
)); 
9

奇怪的是我在2016年面臨着同樣的問題,仍然有很難找到解決方案。我將分享其對未來的Google:

的問題是,什麼樣的symfony基本上沒有當您保存形式是這樣的:

$asset->getUsers()->add($user)

而且因爲你在關係的另一方它將不會堅持你的改變。

你真正需要的是讓這樣它調用此:

$asset->addUser($user)

凡ADDUSER()是指對資產實體的方式如下:

public function addUser(User $user) 
{ 
    //add to the inverse side 
    $this->users->add($user); 

    //add on the owning side (only this is persisted) 
    $user->addAsset($this); //$user->assets->add($asset); 
} 

所以爲了讓symfony使用$asset->addUser()的方法,你應該設置

'by_reference' => false

AssetType表格users場。

更多關於此設置在這裏http://symfony.com/doc/current/reference/forms/types/form.html#by-reference

記住,你還需要以同樣的方式來定義removeUser()方法(以便從所屬關係刪除實體)

+0

這應該是被接受的答案。我想知道,做一些復古發佈,爲什麼沒有人寫這個,並最終把你與你的。好一個。 – DonCallisto 2016-09-15 09:22:09

+0

**資產**在此擁有一方,因此這與[Doctrine Documentation](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#擁有和反對在一個許多tomany協會) – Trix 2017-05-09 13:44:50

+0

@Trix謝謝,我剛剛再次檢查,確實有用戶/資產混淆。我做了一個編輯 - 解決方案仍然是一樣的,我只調整了變量名稱以保持一致。 – 2017-05-11 15:17:59