DonCallisto
DonCallisto

Reputation: 29942

Sonata Admin Bundle and Doctrine issue: how to update an entity from inversed side?

I have a many-to-many relationship between two entities. Let's call those User And Group.

I've decided that onto creation/update interface, because they could be associated, you can directly associate users from group form or groups from user form. Notice that the owning side of relation is User

Now comes the issue. If I associate groups from user form interface, all is good and works perfectly (doctrine looks for changes into owning side). If I try to associate User from group form interface, nothing works.

Obviously I perfectly know that I have to "add" user(s) into group object and add group (this) to every user(s) object that I passed down from form. In fact this is my snippet of code into Group entity

public function setUsers(\Doctrine\Common\Collections\ArrayCollection $utente)
{
    /* snippet of code for removing old association , didn't reported */

    foreach($utente as $u){
        $this->users[] = $u;
        $u->addGroups($this);
    }
}

Into creation form this snippet do well his job. Into update, it doesn't.
So I suppose that this must be a sonata issue or something that, at the moment, I missed.

Any advice?

UPDATE

After some time spent to understand what's going on here, I just find that setUser() isn't called into update operation (read as submit a form builded onto an existent entity). So my code runs only when I create new ones entry ( I still haven't a solution )

Upvotes: 1

Views: 4289

Answers (3)

DonCallisto
DonCallisto

Reputation: 29942

I've just find out how to update the entity.
I suppose that is a Symfony2 related behaviour and not a Sonata Admin one.

In a nutshell, you have to tell Symfony2 to call the setter of the object that you want to update.

For that use:

by_reference => false

In Sonata Admin Bundle case:

$formMapper
            ->add('nome')
            ->add('canali', 'sonata_type_model', array('required' => false))
            ->add('utenti', 'sonata_type_model', array('required' => false,
                                                       'by_reference' => false))
        ;

In pure Symfony2 Form case:

->add('utenti', 'collection', array(
                'type' => new User(),
                'allow_add' => true,
                'allow_delete' => true,
                'prototype' => true,
                'by_reference' => false,
            ))
        ;

Upvotes: 3

Serhii Smirnov
Serhii Smirnov

Reputation: 1357

Try to add the following to your admin class

public function prePersist($group)
{
    $group->setUsers($group->getUsers());
    parent::prePersist($testQuestion);
}

public function preUpdate($group)
{
    $group->setUsers($group->getUsers());
    parent::preUpdate($testQuestion);
}

Upvotes: 0

WizardZ
WizardZ

Reputation: 1397

Unclear what you mean that for update it does not do job well. Based on your code I assume it adds new relations between users and groups but do not remove old.

public function setUsers(\Doctrine\Common\Collections\ArrayCollection $utente)
{
    // to synch internal and external collections, remove relation between users and groups if user is not in the new collection
    foreach ($this->users as $u) {
        if (!$utente->contains($u)) {
            // add this function to user object, it's trivial, just remove give group from internal groups collection
            $u->removeGroup($this); 
        }
    }
    foreach ($utente as $u) {
        if (!$this->users->contains($u)) {
            $this->users[] = $u;
            $u->addGroups($this);
        }
    }
}

Upvotes: 0

Related Questions