Neobyte
Neobyte

Reputation: 396

Hydration of form object that uses Doctrine ObjectSelect

I have an issue attempting to hydrate an object from a form, using ZF2.5 and Doctrine2.

I have a create form with a base fieldset configured for object type A. It is configured with a ClassMethods hydrator and initialised with a "new A()" object. By itself, this form works as expected - from the controller, upon validation, I can call $form->getData() to receive an object of type A which I then persist to the database.

Class A has a manyToOne relationship with Class B. I have attempted to add this relationship to the fieldset mentioned above as follows:

$this->add([
            'name' => 'class_A_field_name_for_class_B',
            'type' => 'DoctrineModule\Form\Element\ObjectSelect',
            'options' => array(
                'object_manager'     => $this->entity_manager,
                'target_class'       => '\my\ClassB',
                'property' => 'name',
                'is_method' => true,
                'label' => 'Class B Selection'
            ),
            'attributes' => [
                'class' => 'form-control',
                'required' => true
            ]
        ]);

Unfortunately, I get an error akin to this:

Argument 1 passed to my\ClassA::setClassB() must be an instance of my\ClassB, string given, called in /vagrant/vendor/zendframework/zend-stdlib/src/Hydrator/ClassMethods.php on line 220 and defined

I cannot work out what I am doing wrong. Any takers? I have tried changing the 'property' field to 'id' but all that does is try and call setClassB(3) instead (rather than hydrating the ClassB instance of id 3 and passing that to setClassB).

Many thanks in advance.

Upvotes: 0

Views: 360

Answers (1)

AlexP
AlexP

Reputation: 9857

The value of the select box when posted will be a string and the ClassMethods hydrator is using this value when calling setClassB($string); which subsequently fails as the method expects an object of type ClassB.

In order for this relationship be hydrated, you will need to use the Doctrine object hydrator, DoctrineModule\Stdlib\Hydrator\DoctrineObject. This hydrator will convert the relevant ids into new (or existing) ClassB instances.

use DoctrineModule\Stdlib\Hydrator\DoctrineObject;

$hydrator = new DoctrineObject($entityManager);
$objectA  = new ClassA();

$data = [
    'name'   => 'New class A',
    'classB' => 4  
);

$objectA = $hydrator->hydrate($data, $objectA);

echo $objectA->getName();    // 'new class A'
echo gettype($objectA->getClassB()); // object of type ClassB

Upvotes: 2

Related Questions