所以我试图在Symfony 2中创建一个包含我的“Person”实体的注册表单。人员实体具有一对多联接,我希望注册表单允许用户选择联接的“多个”一侧的单个实例。
结构为Users
和Institutions
。用户可以拥有许多机构。我希望用户在注册时选择一个机构(但模型允许以后更多)。
基本结构是:
RegistrationType - > PersonType - > PersonInstitutionType
...与相应的型号:
注册(简单模型) - >人(学说实体) - > PersonInstitution(学说实体,来自Person的oneToMany关系)
我试图预先填充空Person
& PersonInstitution
中的RegistrationController
记录,但它给出了错误:
“String或Symfony \ Component \ Form \ FormTypeInterface”,“TB \ CtoBundle \ Entity \ PersonInstitution”类型的预期参数
(上面确定已修复)。
我已将代码从我的网站移到此处,尝试删除所有无关的位。
的src / TB / CtoBundle /窗体/型号/和registration.php
namespace TB\CtoBundle\Form\Model;
use TB\CtoBundle\Entity\Person;
class Registration
{
/**
* @var Person
*/
private $person
private $termsAccepted;
}
的src / TB / CtoBundle /窗体/ RegistrationType.php
namespace TB\CtoBundle\Form;
use TB\CtoBundle\Form\PersonType;
class RegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('person', new PersonType());
$builder->add('termsAccepted','checkbox');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'TB\CtoBundle\Form\Model\Registration',
'cascade_validation' => true,
));
}
public function getName()
{
return 'registration';
}
}
的src / TB / CtoBundle /实体/ Person.php
namespace TB\CtoBundle\Entity;
use TB\CtoBundle\Entity\PersonInstitution
/**
* @ORM\Entity()
*/
class Person
{
/**
* @var ArrayCollection
* @ORM\OneToMany(targetEntity="PersonInstitution", mappedBy="person", cascade={"persist"})
*/
private $institutions;
}
的src / TB / CtoBundle /窗体/ PersonType.php
namespace TB\CtoBundle\Form;
class PersonType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('institutions', 'collection', array('type' => new PersonInstitutionType()))
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'TB\CtoBundle\Entity\Person',
));
}
/**
* @return string
*/
public function getName()
{
return 'tb_ctobundle_person';
}
}
的src / TB / CtoBundle /实体/ PersonInstitution.php
namespace TB\CtoBundle\Entity
/**
* PersonInstitution
*
* @ORM\Table()
* @ORM\Entity
*/
class PersonInstitution
{
/**
* @ORM\ManyToOne(targetEntity="Person", inversedBy="institutions", cascade={"persist"})
*/
private $person;
/**
* @ORM\ManyToOne(targetEntity="Institution", inversedBy="members")
*/
private $institution;
/**
* @ORM\Column(type="boolean")
*/
private $approved;
}
的src / TB / CtoBundle /窗体/ PersonInstititionType.php
namespace TB\CtoBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class PersonInstitutionType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('approved')
->add('person')
->add('institution')
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'TB\CtoBundle\Entity\PersonInstitution'
));
}
/**
* @return string
*/
public function getName()
{
return 'tb_ctobundle_personinstitution';
}
}
的src / TB / CtoBundle /控制器/和registration.php
namespace TB\CtoBundle\Controller;
class RegisterController extends Controller
{
/**
*
* @param Request $request
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
*/
public function registerAction(Request $request)
{
$registration = new Registration;
$person = new Person();
$institution = new PersonInstitution();
$person->addInstitution($institution);
$registration->setPerson($person);
// this causes error:
// Entities passed to the choice field must be managed. Maybe persist them in the entity manager?
// $institution->setPerson($person);
$form = $this->createForm(new RegistrationType(), $registration);
$form->handleRequest($request);
if($form->isValid()) {
$registration = $form->getData();
$person = $registration->getPerson();
// new registration - account status is "pending"
$person->setAccountStatus("P");
// I'd like to get rid of this if possible
// for each "PersonInstitution" record, set the 'person' value
foreach($person->getInstitutions() as $rec) {
$rec->setPerson($person);
}
$em = $this->getDoctrine()->getManager();
$em->persist($person);
$em->flush();
}
return $this->render('TBCtoBundle:Register:register.html.twig', array('form' => $form->createView()));
}
}
答案 0 :(得分:1)
以下是向Person实体和formType添加Collection字段的详细解决方案。 您可以通过此解决注册实体的复杂问题。 如果确实需要,我建议你使用这个与实体相关的3连接。 (仅因为术语接受数据!?)
如果您不会改变您的意见,请使用此注释: 注册码:
use TB\CtoBundle\Entity\Person;
/**
* @ORM\OneToOne(targetEntity="Person")
* @var Person
*/
protected $person;
人员代码:
use TB\CtoBundle\Entity\PersonInstitution;
/**
* @ORM\OneToMany(targetEntity="PersonInstitution", mappedBy = "person")
* @var ArrayCollection
*/
private $institutions;
/* I suggest you to define these functions:
setInstitutions(ArrayCollection $institutions),
getInstitutions()
addInstitution(PersonInstitution $institution)
removeInstitution(PersonInstitution $institution)
*/
PersonInstitution代码:
use TB\CtoBundle\Entity\Person;
/**
* @ORM\ManyToOne(targetEntity="Person", inversedBy="institutions", cascade={"persist"}))
* @var Person
*/
private $person;
PersonType代码:
use TB\CtoBundle\Form\PersonInstitutionType;
->add('institutions', 'collection', array(
'type' => new PersonInstitutionType(), // here is your mistake!
// Other options can be selected here.
//'allow_add' => TRUE,
//'allow_delete' => TRUE,
//'prototype' => TRUE,
//'by_reference' => FALSE,
));
PersonController代码:
use TB\CtoBundle\Entity\Person;
use TB\CtoBundle\Entity\PersonInstitution;
/**
* ...
*/
public funtcion newAction()
{
$person = new Person;
$institution = new PersonInstitution;
$institution->setPerson($person);
$person->addInstitution($institution);
$form = $this->createForm(new PersonType($), $person); // you can use formFactory too.
// If institution field is required, then you have to check,
// that is there any institution able to chose in the form by the user.
// Might you can redirect to institution newAction in that case.
return array( '...' => $others, 'form' => $form);
}
如果您在twig代码中需要更多帮助,请提出要求。