在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()
中正确地做的那样)