Symfony2 1:M / 1:1 Relationship and Sonata Admin Form

doctrine-orm, sonata-admin, symfony, symfony-sonata

Solution

For those running into the same problem, I posted the solution on GitHub

.

Problem

I've hitting my head against the wall for countless hours now and I hope SO can be of help! I have Retailer, Branch and RetailerBranches entities which work just fine, retailers can have many branches and a branch can only have one retailer. The hard part happens when trying to make Sonata Admin (SonataAdminBundle) play nice with that relationship. In their simplest form, they look like this: Retailer entity ``` /** * @ORM\Column(name="ID", type="integer", nullable=false) * @ORM\Id * @ORM\GeneratedValue(strategy="IDENTITY") */ private $id; /** * Relation * * @ORM\OneToMany(targetEntity="RetailerBranches", mappedBy="Retailer", cascade={"persist"}) */ protected $branches; public function __construct() { $this->branches = new ArrayCollection(); } ``` RetailerBranches join table ``` /** * @ORM\Column(name="ID", type="integer", nullable=false) * @ORM\Id * @ORM\GeneratedValue(strategy="IDENTITY") */ private $id; /** * @ORM\JoinColumn(name="Retailer_ID", referencedColumnName="ID", nullable=false) * @ORM\ManyToOne(targetEntity="Retailer", inversedBy="branches") */ private $retailer; /** * @ORM\JoinColumn(name="Branch_ID", referencedColumnName="ID", nullable=false, unique=true) * @ORM\OneToOne(targetEntity="Branch", inversedBy="retailer") */ private $branch; ``` Branch entity ``` /** * @ORM\Column(name="ID", type="integer", nullable=false) * @ORM\Id * @ORM\GeneratedValue(strategy="IDENTITY") */ private $id; /** * Relation * * @ORM\OneToOne(targetEntity="RetailerBranches", mappedBy="branch", cascade={"persist"}) */ private $retailer; ``` The harder part happens when trying generate the form to allow that relationship to take shape: RetailerAdmin ``` protected function configureFormFields(FormMapper $formMapper) { $formMapper ->with('Branches') ->add('branches', 'sonata_type_collection', array( 'required' => false, 'by_reference' => false ), array( 'edit' => 'inline', 'inline' => 'table', )) ->end() ; } ``` RetailerBranchesAdmin ``` protected function configureFormFields(FormMapper $formMapper) { if ($this->hasRequest()) { $link_parameters = array('context' => $this->getRequest()->get('context')); } else { $link_parameters = array(); } $formMapper ->add('succursale', 'sonata_type_model_list', array( 'class' => 'VeloRetailerBundle:Branch', 'required' => false, ), array( 'edit' => 'inline', 'inline' => 'table', )) ; } ``` The problem: All this sort of works, here's a screenshot: There's a Retailer and its Branches. Yay. Problem 1: The "Add new" button at the bottom attempts to add a RetailerBranches object instead of a simple Branch object which obviously doesn't work. Problem 2: This method also doesn't allow the user to modify a Branch inline. I feel like I'm close to the solution, but I just cannot quite get there. Any help would be greatly appreciated!

Original source