使用 Doctrine ObjectSelect 的表单对象的水化

Hydration of form object that uses Doctrine ObjectSelect

我在尝试使用 ZF2.5 和 Doctrine2 从表单中混合对象时遇到问题。

我有一个创建表单,其中为对象类型 A 配置了一个基本字段集。它配置了一个 ClassMethods hydrator 并用一个 "new A()" 对象初始化。就其本身而言,此表单按预期工作 - 从控制器,在验证后,我可以调用 $form->getData() 来接收类型 A 的对象,然后我将其保存到数据库中。

Class A 与 Class B 存在多对一关系。我尝试将此关系添加到上述字段集中,如下所示:

$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
            ]
        ]);

不幸的是,我收到了类似这样的错误:

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

我不知道我做错了什么。有接盘者吗?我已经尝试将 'property' 字段更改为 'id' 但所做的只是尝试调用 setClassB(3) 而不是(而不是水化 id 的 ClassB 实例3 并将其传递给 setClassB).

非常感谢。

发布时 select 框的值将是一个字符串,ClassMethods hydrator 在调用 setClassB($string) 时使用该值;随后失败,因为该方法需要类型为 ClassBobject

为了滋润这段关系,您需要使用Doctrine object hydrator, DoctrineModule\Stdlib\Hydrator\DoctrineObject。此水化器会将相关 ID 转换为新的(或现有的)ClassB 个实例。

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