php - Symfony 2 - Multiple entities with one form -
i've got following tables relationships:
useraddress
table (holds basic information address)useraddressfields
table (holds value each field associated address)useraddressfieldstranslation
table (holds field ids)userstates
table (holds values of states in , abbreviations)
useraddress has 2 foreign keys:
profile_id
->useraccounts.id
state_id
->userstates.id
useraddressfields has 1 foreign key:
address_id
->useraddress.id
i've created entities 4 of these tables (getters , setters have been removed save space, generated via console):
useraddress.php
<?php namespace scwdesignsbundle\entity; use doctrine\orm\mapping orm; use scwdesignsbundle\entity\userstates; use usersbundle\entity\user; /** * @orm\entity(repositoryclass="scwdesignsbundle\entity\repository\ useraddressesrepository") * @orm\table(name="user_addresses") */ class useraddresses { /** * @orm\id * @orm\column(type="integer") * @orm\generatedvalue(strategy="auto") */ protected $id; /** * @orm\manytoone(targetentity="usersbundle\entity\user") * @orm\joincolumn(name="profile_id", referencedcolumnname="id") */ protected $profile_id; /** * @orm\manytoone(targetentity="userstates") * @orm\joincolumn(name="state_id", referencedcolumnname="id") */ protected $state_id; /** * @orm\column(type="boolean") */ protected $isbilling; /** * @orm\column(type="boolean") */ protected $isshipping; /** * @orm\column(type="string", columndefinition="char(1)") */ protected $addresstype;
useraddressfieldstranslation.php
<?php namespace scwdesignsbundle\entity; use doctrine\orm\mapping orm; use scwdesignsbundle\entity\useraddressfields; use usersbundle\entity\user; /** * @orm\entity(repositoryclass="scwdesignsbundle\entity\repository\useraddressfieldstranslationrepository") * @orm\table(name="user_address_fields_translation") */ class useraddressfieldstranslation { /** * @orm\id * @orm\column(type="integer") * @orm\generatedvalue(strategy="auto") */ protected $id; /** * @orm\column(type="string", columndefinition="varchar(255) not null") */ protected $name;
userstates.php
<?php namespace scwdesignsbundle\entity; use doctrine\orm\mapping orm; /** * @orm\entity(repositoryclass="scwdesignsbundle\entity\repository\statesrepository") * @orm\table(name="user_states") */ class userstates { /** * @orm\id * @orm\column(type="integer") * @orm\generatedvalue(strategy="auto") */ protected $id; /** * @orm\column(type="string", columndefinition="char(2)") */ protected $country_code; /** * @orm\column(type="string", columndefinition="varchar(64)") */ protected $state;
i have 2 form types, useraddressformtype , useraddressfieldsformtype.
useraddressformtype
<?php namespace scwdesignsbundle\form\type; use symfony\component\form\abstracttype; use symfony\component\form\formbuilderinterface; use symfony\component\optionsresolver\optionsresolverinterface; class useraddressformtype extends abstracttype { public function buildform(formbuilderinterface $builder, array $options) { $builder ->add('profile_id', null, array('label' => 'profile id')) ->add('state_id', null, array('label' => 'state id')) ->add('isbilling', null, array('label' => 'billing address')) ->add('isshipping', null, array('label' => 'shipping address')) ->add('addresstype', null, array('label' => 'address type')) ->add('addressfields', new useraddressfieldsformtype()); } public function setdefaultoptions(optionsresolverinterface $resolver) { $resolver->setdefaults(array( 'data_class' => 'scwdesignsbundle\entity\useraddresses' )); } public function getname() { return 'useraddressformtype'; } }
useraddressfieldsformtype.php
<?php namespace scwdesignsbundle\form\type; use symfony\component\form\abstracttype; use symfony\component\form\formbuilderinterface; use symfony\component\optionsresolver\optionsresolverinterface; class useraddressfieldsformtype extends abstracttype { public function buildform(formbuilderinterface $builder, array $options) { $builder ->add('address_id', null, array('label' => 'address field')) ->add('address_field_id', null, array('label' => 'address field id')) ->add('value', null, array('label' => 'value')); } public function setdefaultoptions(optionsresolverinterface $resolver) { $resolver->setdefaults(array( 'data_class' => 'scwdesignsbundle\entity\useraddressfields' )); } public function getname() { return 'useraddressfieldsformtype'; } }
in controller basic form call. profilecontroller.php
<?php namespace scwdesignsbundle\controller; use symfony\bundle\frameworkbundle\controller\controller; use symfony\component\httpfoundation\response; use scwdesignsbundle\entity\useraddresses; use scwdesignsbundle\form\type\useraddressformtype; use scwdesignsbundle\form\type\useraddressfieldsformtype; class profilecontroller extends controller { public function editaddressaction() { $address = new useraddresses(); $form_address = $this->createform(new useraddressformtype(), $address); $request = $this->getrequest(); if ($request->getmethod() == 'post') { // perform action. return $this->redirect($this->generateurl('fos_user_profile_show')); } return $this->render('scwdesignsbundle:profile:edit.html.twig', array( 'active_page' => 'profile', 'form_address' => $form_address->createview(), )); } }
everywhere i've read correct means of adding entity form builder everytime this, or other variation i've ran across following error
neither property "addressfields" nor 1 of methods "getaddressfields()", "isaddressfields()", "hasaddressfields()", "__get()" exist , have public access in class "scwdesignsbundle\entity\useraddresses".
so in first form set defaults this:
$resolver->setdefaults(array( 'data_class' => 'scwdesignsbundle\entity\useraddresses' ));
so field add expected correspond field in entity. think geob right. need add mapping want, if want on class or make form independent of entity (so remove 'data_class' option defaults). add mapping consider following code onetomany relation:
/** * @orm\onetomany(targetentity="useraddressfields", mappedby="user_address", cascade={"persist", "remove"}) */ protected $addressfields; public function addaddressfield($addressfield) { $this->addressfields[] = $addressfield; } public function removeaddressfield() {...} public function getaddressfields() {...} public function __construct() { $this->addressfields = new arraycollection(); }
and if combine nawfal's answer:
$builder->add('addressfields', 'collection', array('type' => new useraddressfieldsformtype()));
it should work!