使用doctrine embeddables和symfony表单时是否有人遇到此问题?
如果你不了解Doctrine Embeddables,你可以在这里阅读 http://doctrine-orm.readthedocs.org/en/latest/tutorials/embeddables.html
在表单提交中使用带有symfony表单的值对象(在我的情况下为CategoryType)时(在持久化到DB期间),我收到以下警告
警告:ReflectionProperty :: getValue()要求参数1为对象,给定字符串
这是因为symfony表单返回字符串而不是embeddable对象。
我现在唯一的解决方法是在mapped => false
字段上使用type
,并在持久化之前在控制器操作中创建有效的可嵌入对象。但那远远不是很好的"解决方案,我想避免这种情况。
我的实体,价值对象和形式(为了提问而简化)
富\ BarBundle \实体\ CategoryType
<?php
namespace Foo\BarBundle\Entity;
class CategoryType
{
/**
* @var string
*/
protected $value;
public function __toString()
{
return (string) $this->getValue();
}
/**
* @return string
*/
public function getValue()
{
return $this->value;
}
/**
* @param string $value
*
* @return $this
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
}
富\ BarBundle \资源\配置\教义\ CategoryType.orm.yml
CategoryType.orm.yml
Foo\BarBundle\Entity\CategoryType:
type: embeddable
fields:
value:
type: string
富\ BarBundle \实体\类别的
<?php
namespace Foo\BarBundle\Entity;
class Category
{
/**
* @var integer
*/
protected $id;
/**
* @var string
*/
protected $name;
/**
* @var CategoryType
*/
protected $type;
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @return \Foo\BarBundle\Entity\CategoryType
*/
public function getType()
{
return $this->type;
}
/**
* @param \Foo\BarBundle\Entity\CategoryType $type
*
* @return $this
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* @return string
*/
public function __toString()
{
return (string) $this->getName();
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param string $name
*
* @return $this
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
}
富\ BarBundle \资源\配置\教义\ Category.orm.yml
Foo\BarBundle\Entity\Category:
type: entity
fields:
id:
type: integer
id: true
generator:
strategy: AUTO
name:
type: string
embedded:
type:
class: CategoryType
富\ BarBundle \表格\ CategoryType
<?php
namespace Foo\BarBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class CategoryType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('type')
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'Foo\BarBundle\Entity\Category'
)
);
}
/**
* @return string
*/
public function getName()
{
return 'category_form';
}
}
答案 0 :(得分:4)
doctrine embedabble行为只是一种持久性机制,因此,它不能破坏与其无关的表单组件(并且适用于所有对象图)。
问题是您的表单设计不合理(它不遵循您的对象图)。在这里,您有一个包装类别类型的类别。因此,您的表单必须在定义级别遵循相同的结构。
您必须创建一个CategoryTypeType
表单(映射到您的CategoryType
类),其中添加value
字段。然后,在CategoryType
(表单1)中,您必须为CategoryTypeType
字段嵌入type
。
然后,表单组件将自动创建一个包裹Category
的{{1}}。然后,Doctrine会简单地将您的对象保持为可嵌入状态,并且一切都会正常工作:)