【问题标题】:Symfony CollectionType with "allow_add" not adding child entity to parent entity带有“allow_add”的 Symfony CollectionType 不将子实体添加到父实体
【发布时间】:2016-09-15 03:27:19
【问题描述】:

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

联系方式:

class Contact
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue
     */
    protected $id;

    /**
     * @ORM\Column
     * @Assert\NotBlank
     */
    protected $name;

    /**
     * @ORM\OneToMany(targetEntity="EmailContact", mappedBy="contact", cascade={"persist"})
     * @Assert\Valid
     */
    protected $emails;

    // ...

    /**
     * Add emails
     *
     * @param \AppBundle\Entity\EmailContact $emails
     * @return Contact
     */
    public function addEmail(\AppBundle\Entity\EmailContact $emails)
    {
        $this->emails[] = $emails;
        $emails->setContact($this);  //this line added by me

        return $this;
    }

    // ...

电子邮件联系方式:

class EmailContact
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue
     */
    protected $id;

    /**
     * @ORM\Column
     * @Assert\NotBlank
     */
    protected $email;

    /**
     * @ORM\ManyToOne(targetEntity="Contact", inversedBy="emails")
     * @ORM\JoinColumn(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' => 'AppBundle\Entity\Contact'
        ]);
    }

电子邮件联系人类型:

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' => 'AppBundle\Entity\EmailContact'
        ]);
    }

我使用 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 方法永远不会被调用。这里发生了什么?

【问题讨论】:

标签: forms collections doctrine-orm symfony


【解决方案1】:

您在表单集合定义中错过了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
]);

看看here

您的代码应在此修改后按预期运行。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-12
    相关资源
    最近更新 更多