尽管cascade_validation为false,但Symfony2嵌入表单无效

时间:2014-01-06 20:18:25

标签: forms symfony

在表单(ContractType)中,我需要与Customer建立关联,Customer本身与公司和BillingAddress有关联。但是这些3个“嵌套实体”的数据本身在合同视图中根本不可编辑。这就是合同中客户ManyToOne-Relation的字段隐藏的原因。

但是出于显示目的,我还需要表格中的整个客户对象(包括底层公司和账单地址) - 但是只读。这就是为什么我在合同表单类型中添加了一个额外的字段 customerFullObject - 未映射( mapped => false )。由于它是一个未映射的字段,我通过表单事件设置数据。

现在,当我编辑合同数据时,客户的公司和账单地址数据无效 如果我删除/评论整个 customerFullObject 部分,一切都很好。

我不明白,未映射字段如何/为何可以更改实体的数据。 如何防止Symfony呢?或者是否有更好的“模式”/方式来实现我想要的?我在文档中找不到任何内容。

以下来自模型的一些代码段(为了简洁而删除了名称空间):

Contract.php

/**
 * @ORM\Entity
 */
class Contract {
    /**
     * @var Customer
     * @ORM\ManyToOne(targetEntity="Customer", inversedBy="contracts")
     * @Assert\Type(type="Customer")
     * @Assert\NotBlank(message = "customer.notBlank")
     **/
    private $customer;

    // Other fields left out as irrelevant.
}

Customer.php

/**
 * @ORM\Entity
 */
class Customer {
    /**
     * @var Company
     * @ORM\OneToOne(targetEntity="Company")
     * @Assert\NotBlank(message="company.notBlank")
     **/
    private $company;

    /**
     * @var Address
     * @ORM\OneToOne(targetEntity="Address")
     * @Assert\NotBlank(message="billingAddress.notBlank")
     **/
    private $billingAddress;

    /**
     * @var ArrayCollection
     * @ORM\OneToMany(targetEntity="Contract", mappedBy="customer", orphanRemoval=true, cascade={"all"})
     **/
    private $contracts;

    // Other fields left out as irrelevant.
}

ContractType.php

class ContractType extends AbstractType {
    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->add(
            'customer',
            'customerHiddenType',
            array(
                'label' => 'contract.customer',
            )
        );

        $builder->add(
            'customerFullObject',
            'customerType',
            array(
                'cascade_validation' => false,
                'mapped' => false
            )
        );

        $builder->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) {
                $form = $event->getForm();
                $editMode = $form->getConfig()->getOption('editMode');
                if (!empty($editMode) && $editMode === RequestAction::CREATE()) {
                    $form->remove('customerFullObject');
                } else {
                    $form->get('customerFullObject')->setData($event->getData()->getCustomer());
                }
            }
        );

        // Other children left out as irrelevant.
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        $resolver->setDefaults(
             array(
                 'data_class' => 'Contract',
                 'cascade_validation' => true
             )
        );
    }

    public function getName() {
        return 'contractType';
    }
}

CustomerType.php

class CustomerType extends AbstractType {
    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->add(
            'company',
            'companyType',
            array(
                'cascade_validation' => false,
                'label' => 'customer.company'
            )
        );

        $builder->add(
            'billingAddress',
            'addressType',
            array(
                'cascade_validation' => false,
                'label' => 'customer.billingAddress'
            )
        );

        // Other children left out as irrelevant.
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        $resolver->setDefaults(
             array(
                 'data_class' => 'Customer',
                 'cascade_validation' => true
             )
        );
    }

    public function getName() {
        return 'customerType';
    }
}

0 个答案:

没有答案
相关问题