问题
I was following along with the Doctrine Hydrator tutorial, but I am having issues saving when my fieldset contains an ObjectSelect. I'm using ORM mapping on my entities. Basically I have a Role
entity with id
and name
. I also have a User
entity with id
, name
and role
(ManyToOne). I also have my getters and setters. My setRole()
method passes the Role
entity as a parameter.
/** @param Role $role */
public function setRole(\Application\Entity\Role $role) {
$this->role = $role;
}
I setup a UserFieldset with a Doctrine Hydrator.
$this->setHydrator(new DoctrineHydrator($objectManager, 'Application\Entity\User'))
->setObject(new User());
The object select for the Role
$this->add(array(
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'name' => 'role',
'options' => array(
'label' => 'Role',
'object_manager' => $objectManager,
'target_class' => 'Application\Entity\Role',
'property' => 'name'
)
));
I then setup a UserForm that sets the DoctrineHydrator and adds the UserFieldset.
My controller action
public function addUserAction() {
$objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
$form = new UserForm($objectManager);
$user = new User();
$form->bind($user);
if ($this->request->isPost()) {
$form->setData($this->request->getPost());
if ($form->isValid()) {
$objectManager->persist($user);
$objectManager->flush();
}
}
return array('form' => $form);
}
What seems to be happening is that the ID of the role is passed to setRole rather than an object. As a workaround I've modified my action to:
if ($form->isValid()) {
$objectManager->persist($user);
$data = $this->request->getPost();
$role = $objectManager->find('Application\Entity\Role', $data->user['role']);
$user->setRole($role);
$objectManager->flush();
}
It seems as if this additional step should not be required, but I am not sure if I need to modify my setRole or if I also need to bind a Role entity to the form. This is obviously a simplified example, but my actual forms have many associations that will be tedious to have to code in the controller like this.
UPDATE: Debug information about post and form.
var_dump($form->getData());
var_dump($this->request->getPost());
Output
object(Application\Entity\User)[395]
protected 'id' => int 6
protected 'name' => string 'Jane Doe' (length=8)
protected 'role' => null
object(Zend\Stdlib\Parameters)[146]
public 'user' =>
array (size=3)
'id' => string '' (length=0)
'name' => string 'Jane Doe' (length=8)
'role' => string '3' (length=1)
public 'submit' => string 'Add User' (length=8)
回答1:
At long last I got it working. The issue was that I needed to add the role to my input filter on the fieldset
public function getInputFilterSpecification() {
return array(
'name' => array('required' => true),
'role' => array('required' => true)
)
}
... and my validation group on my form.
$this->setValidationGroup(array(
'User' => array(
'name',
'role'
)
));
Now to save the user in my action it is simply
if ($form->isValid()) {
$objectManager->persist($user);
$objectManager->flush();
}
来源:https://stackoverflow.com/questions/19284826/saving-a-doctrine-2-entity-that-contains-an-objectselect-element-using-zend-form