Doctrine OneToOne Bi和Unidirectional与ZF2 Fieldsets不保存/保湿

时间:2016-12-04 21:31:18

标签: doctrine-orm zend-framework2

我有2个Doctrine实体(EnvironmentEnvironmentConfig)。他们有bi-directional OneToOne 的关系。

每个实体都有自己的Fieldset,以便重复使用。

要创建Environment,它也可以有EnvironmentConfig,但不是必需的。为了让它们同时制作,我有EnvironmentForm使用EnvironmentFieldsetEnvironmentConfigFieldset

表单正确呈现。但是,它会保存Environment,但不保存EnvironmentConfig

我在设置它以及如何修复它时出错了?

下面的代码,遗漏了getter / setter,太多了。

实体

// abstract class AbstractEntity has $id + getters/setters.

class Environment extends AbstractEntity
{
    /**
     * @var string
     * @ORM\Column(name="name", type="string", length=255, nullable=false)
     */
    protected $name;

    /**
     * @var EnvironmentConfig
     * @ORM\OneToOne(targetEntity="Environment\Entity\EnvironmentConfig", inversedBy="environment")
     */
    protected $config;

    /**
     * @var EnvironmentScript
     * @ORM\OneToOne(targetEntity="EnvironmentScript")
     */
    protected $script;

    //Getters/setters
}

class EnvironmentConfig extends AbstractEntity
{
    /**
     * @var string
     * @ORM\Column(name="name", type="string", length=255, nullable=false)
     */
    protected $name;

    /**
     * @var Environment
     * @ORM\OneToOne(targetEntity="Environment\Entity\Environment", mappedBy="config")
     */
    protected $environment;

    //Getters/setters
}

字段集

class EnvironmentFieldset extends AbstractFieldset
{
    /**
     * {@inheritdoc}
     */
    public function init()
    {
        //Loads id element validation
        parent::init();

        $this->add([
            'name' => 'name',
            'type' => Text::class,
            'options' => [
                'label' => _('Name'),
                'label_attributes' => [
                    'class' => 'col-xs-2 col-form-label',
                ],
            ],
            'attributes' => [
                'id' => 'name',
                'class' => 'form-control'
            ],
        ]);

        $this->add([
            'name' => 'environment_config',
            'type' => EnvironmentConfigFieldset::class,
            'options' => [
                'use_as_base_fieldset' => false,
            ],
        ]);

        $this->add([
            'type' => ObjectSelect::class,
            'name' => 'environment_script',
            'options' => [
                'object_manager' => $this->getEntityManager(),
                'target_class'   => EnvironmentScript::class,
                'property'       => 'id',
                'display_empty_item' => true,
                'empty_item_label'   => '---',
                'label_generator' => function ($targetEntity) {
                    return $targetEntity->getId() . ' - ' . $targetEntity->getName();
                },
            ],
        ]);
    }
}

class EnvironmentConfigFieldset extends AbstractFieldset
{
    /**
     * {@inheritdoc}
     */
    public function init()
    {
        //Loads id element validation
        parent::init();

        $this->add([
            'name' => 'name',
            'type' => Text::class,
            'options' => [
                'label' => _('Name'),
                'label_attributes' => [
                    'class' => 'col-xs-2 col-form-label',
                ],
            ],
            'attributes' => [
                'id' => 'name',
                'class' => 'form-control'
            ],
        ]);

    }
}

表格

class EnvironmentForm extends AbstractForm
{
    /**
     * EnvironmentForm constructor.
     * @param null $name
     * @param array $options
     */
    public function __construct($name = null, array $options)
    {
        //Also adds CSRF
        parent::__construct($name, $options);
    }

    /**
     * {@inheritdoc}
     */
    public function init()
    {
        //Call parent initializer. Adds submit button.
        parent::init();

        $this->add([
            'name' => 'environment',
            'type' => EnvironmentFieldset::class,
            'options' => [
                'use_as_base_fieldset' => true,
            ],
        ]);
    }
}

编辑:添加了调试数据和AddAction() Debug of form and request data

以上函数中persist()行的上述调试完成。

public function addAction($formName, array $formOptions = null, $route, array $routeParams = [])
{
    if (!$this->formElementManager instanceof FormElementManagerV2Polyfill) {

        throw new InvalidArgumentException('Dependency FormElementManagerV2Polyfill not set. Please check Factory for this function.');
    }

    if (!class_exists($formName)) {

        throw new ClassNotFoundException('Given class could not be found. Does it exist?');
    }

    /** @var AbstractForm $form */
    $form = $this->getFormElementManager()->get($formName, (is_null($formOptions) ? [] : $formOptions));

    /** @var Request $request */
    $request = $this->getRequest();
    if ($request->isPost()) {
        $form->setData($request->getPost());

        if ($form->isValid()) {
            $entity = $form->getObject();

            $this->getEntityService()->getEntityManager()->persist($entity);
            $this->getEntityService()->getEntityManager()->flush();

            $this->flashMessenger()->addSuccessMessage(
                _('Successfully created object.')
            );

            $this->redirectToRoute($route, $this->getRouteParams($entity, $routeParams));
        }
    }

    return [
        'form' => $form,
        'validationMessages' => $form->getMessages() ?: '',
    ];
}

1 个答案:

答案 0 :(得分:1)

您创建了一个名为'environment_config'的字段,但在课程Environment中,您调用了protected $config;。两个名称必须相同。 'environment_script'字段和$script属性的问题相同。

另一方面,您想要动态创建EnvironmentConfig,因此您必须在$config注释中添加cascade选项,才能从{{1}创建$config }}:

Environment