2012-02-01 7 views
18

Mam problem z wieloma związkami. Mam Users i Assets. Chciałbym móc przypisać użytkowników do zasobu na stronie zasobów.Symfony2 Doctrine2 Wiele do wielu postaci nie zapisuje się w obiektach

Poniższy kod wyświetla listę użytkowników podczas tworzenia/edycji zasobu, jednak zmiany dokonane w polach wyboru użytkownika nie zapisują, podczas gdy pozostałe dane są utrwalone.

Jeśli dodaję wpis do users_assets za pośrednictwem klienta mysql, zmiany te są wyświetlane na liście zasobów.

użytkownika

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

aktywami

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

Nie powinieneś chanage 'null' do' EntityType'? Co masz na myśli przez zero ?! – Trix

Odpowiedz

29

Z jakiegoś powodu musiałem przełączyć mapowania doktryny uzyskać to do pracy:

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; 

Teraz kiedy zapisać zasób zapisuje użytkowników powiązanych. Nie musiałem definiować konstruktora-> dodawać jako encji lub kolekcji. I po prostu przekazać ją nieważną i wykorzystuje informacje odwzorowania wypełnić informacji podmiocie:

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

Nie dokładnie pewien, dlaczego musiałem mieć inversedBy i JoinTable info na aktywach vs użytkownik ale wydaje się działać teraz!

Dzięki za sugestie !!!

+0

Miałem podobne problemy. Sugestie dla innych: upewnij się, że wszystkie twoje jednostki/liczby mnogie są takie, jak powinny, a jeśli któraś z twoich jednostek ma nazwę wieloznaczną (np. 'CoolDude'), możesz odnieść korzyść wiedząc, że domyślna wartość Doctrine to Załóżmy, że twoja nazwa tabeli jest po prostu wersją o małych rozmiarach, np 'cooldude'. Jeśli to faktycznie "cool_dude", myślę, że będziesz musiał to jawnie ustawić. Możesz zobaczyć, jak w Doctrine docs. http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/association-mapping.html#many-to-many-bidirectional –

+0

Problem polega na tym, że potrzebujesz podobnej formy na odwrotna strona: to by nie działało. –

+0

Rozwiązanie nie działa dla mnie, mój stół dołączenia jest zawsze pusty! – Fabien

0

Trzeba użyć 'zbieranie' FIE Ld wpisz w formularzu.

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

Najpierw trzeba najpierw utworzyć formularz UserType().

Oto wszystkie informacje trzeba będzie, w tym próbki kodu:

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

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

+0

Myślałem, że przez podanie wartości null zakładamy, że jest to typ, poprzez moje mapowania doktryn. Mam podobną konfigurację, używając kategorii na zasobach i działa świetnie. To jest kod, który muszę wypełnić kolekcje kategorii: -> dodaj ("kategorie", null, tablica ("rozwinięte" => "prawda", "wiele" => "prawda")) ... także ja nie trzeba dodać funkcję crud dla użytkowników w zasobie, a po prostu muszę mieć możliwość przypisania aktualnych użytkowników do tego zasobu. –

+1

Rzeczywiście, doktryna z rozszerzenia dodaje guessser na podstawie metadanych. Jeśli poprawnie zdefiniowałeś swoje powiązanie ManyToMany, guessser typu skonfiguruje twoje pole jako 'collection'. Przez * poprawnie *, mam na myśli to, że ** właściciel ** stowarzyszenia musi być "zasobem" w twoim przypadku, dlatego musisz odwrócić swoje mapowanie. – Florian

+0

Jaki jest problem z 'EntityType' +' Expanded' + 'Multiple'? – Trix

4

Na początku należy upuścić ukośnika prefiks w adnotacji (patrz zauważyć here).

I trzeba użyć typu pola jednostki:

$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'); 
    }, 
)); 
17

Nie dokładnie pewien, dlaczego musiałem mieć inversedBy i JoinTable info na aktywach vs użytkownik ale wydaje się być teraz działa!

Powodem, dla którego twoje zmiany zostały zignorowane, jest to, że doktryna wciąż zmienia się tylko po stronie posiadania relacji (jak @Florian powiedział).

tym odnośnikiem do dokumentacji doktryny, gdzie takie zachowanie jest wyjaśnione: http://docs.doctrine-project.org/en/latest/reference/unitofwork-associations.html

9

Weird wystarczająco I w obliczu tego samego problemu w 2016 roku i wciąż miał trudności ze znalezieniem rozwiązania. będę dzielić go dla przyszłych pracowników Google:

Problemem jest to, że to, co w istocie ma symfony po zapisaniu formularza to:

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

A ponieważ jesteś na odwrotnej stronie relacji to nie utrwali zmian.

Co naprawdę trzeba to zrobić tak, że nazywa to:

$asset->addUser($user)

Gdzie adduser() jest zdefiniowana w następujący sposób na jednostkę aktywów:

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); 
} 

Aby więc symfony użył tej metody, należy ustawić

'by_reference' => false

na polu users dla AssetType formie.

Więcej informacji na temat tego ustawienia w tym http://symfony.com/doc/current/reference/forms/types/form.html#by-reference

Remember trzeba także określić removeUser() metodę w ten sam sposób (tak, że usuwa podmiot z relacji posiadanie)

+0

To powinna być zaakceptowana odpowiedź.Zastanawiałem się, robiąc retrospekcję, dlaczego nikt tego nie napisał i w końcu przywiózł cię ze sobą. Niezłe. – DonCallisto

+0

** Asset ** ma tutaj swoją stronę, dlatego jest to sprzeczne z [Doctrine Documentation] (http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html# posiadanie i odwrotne powiązanie na wiele osób) – Trix

+0

@Trix Dzięki, właśnie sprawdziłem to ponownie i rzeczywiście nastąpiło zamieszanie użytkownika/aktywów. Zrobiłem edycję - rozwiązanie jest wciąż takie samo, dostosowałem tylko nazwy zmiennych, by były spójne. –