Saturday, December 28, 2013

SonataAdminBundle forms One to Many or Many to Many does not persist

This problem occurs due to the inverse-side object is not defined in the owning-side. In order to solve this, we have to manually specify it in the owning-side class. Suppose that we have a user class and a role class that are inverse-side and owning-side respectively. Here is the example of defining the inverse-side object.
//Acme/Bundle/DemeBundle/Entity\User
public function addRole(\Enstb\Bundle\VisplatBundle\Entity\Role $role)
{
    // Link each role with the user 
    // (This is important for SonataAdminBundle!!)
    $role->addUser($this);
    $this->roles->add($role);
    return $this;
}
public function removeRole(\Enstb\Bundle\VisplatBundle\Entity\Role $role)
{
    // Link each role with the user
    $role->removeUser($this);
    $this->roles->removeElement($role);
}
public function getRoles()
{
    return $this->roles;
}
The most important part is $role->addUser($this). It sends the object of Users class to be added in the Roles class. This makes the SonataAdminBundle to realize that which object should be linked together and persisted to a database.
And here is an example of addUser method in the Roles class:
//Acme/Bundle/DemeBundle/Entity\Role
public function addUser(\Enstb\Bundle\VisplatBundle\Entity\Users $user)
{
    $this->Users->add($user);
    return $this;
} 
Note: if you are not sure what is owning-side and inverse-side, read more about What is the difference between inversedBy and mappedBy?.