Symfony CollectionType "allow_add"不将子实体添加到父实体



在Symfony 2.8上,我得到了以下实体:

联系人:

class Contact
{
    /**
     * @ORMId
     * @ORMColumn(type="integer")
     * @ORMGeneratedValue
     */
    protected $id;
    /**
     * @ORMColumn
     * @AssertNotBlank
     */
    protected $name;
    /**
     * @ORMOneToMany(targetEntity="EmailContact", mappedBy="contact", cascade={"persist"})
     * @AssertValid
     */
    protected $emails;
    // ...
    /**
     * Add emails
     *
     * @param AppBundleEntityEmailContact $emails
     * @return Contact
     */
    public function addEmail(AppBundleEntityEmailContact $emails)
    {
        $this->emails[] = $emails;
        $emails->setContact($this);  //this line added by me
        return $this;
    }
    // ...

电子邮件联系方式:

class EmailContact
{
    /**
     * @ORMId
     * @ORMColumn(type="integer")
     * @ORMGeneratedValue
     */
    protected $id;
    /**
     * @ORMColumn
     * @AssertNotBlank
     */
    protected $email;
    /**
     * @ORMManyToOne(targetEntity="Contact", inversedBy="emails")
     * @ORMJoinColumn(nullable=false)
     */
    protected $contact;
    // ...

其余方法由doctrine:generate:entities命令自动生成。

我的表格如下:

联系人类型:

class ContactType extends AbstractType
{   
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', null, [
                'label' => 'contact.name',
            ])
            ->add('emails', CollectionType::class, [
                'label' => false,
                'entry_options' => array('label' => false),
                'entry_type' => EmailContactType::class,
                'allow_add' => true,
                'allow_delete' => true,
                'delete_empty' => true,
                'prototype' => true,
            ])
        ;
    }
    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => 'AppBundleEntityContact'
        ]);
    }

电子邮件联系人类型:

class EmailContactType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('email', EmailType::class, [
                'label' => 'emailContact.email',
            ])                
        ;
    }
    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => 'AppBundleEntityEmailContact'
        ]);
    }

我使用javascript为请求添加额外的字段并提交。示例请求(来自Symfony Profiler):

[ 
name => test4,
emails => [ 
    0 => [ 
        email => t@t.t4
    ], 
    1 => [ 
        email => t@t.t5
    ] 
], 
_token => ...
]

但我得到以下错误:

An exception occurred while executing 'INSERT INTO email_contact ...
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'contact_id' cannot be null 

调试时,我看到上面的addEmail方法从未被调用。这里发生了什么?

您在表单集合定义中错过了by_reference => false

->add('emails', CollectionType::class, [
    'label' => false,
    'entry_options' => array('label' => false),
    'entry_type' => EmailContactType::class,
    'allow_add' => true,
    'allow_delete' => true,
    'delete_empty' => true,
    'prototype' => true,
    'by_reference' => false; // <--- you missed this
]);

看看这里

修改后,您的代码应该按预期运行。

此外,请记住,如果在Contact类中有一个setEmails()方法,那么框架最终会调用它,因此您需要(对于集合的每个元素)也设置联系人(就像在addEmails()中正确地做的那样)

相关内容

  • 没有找到相关文章

最新更新