如果你不知道Doctrine Embeddables是,你可以在这里阅读这里 http://doctrine-orm.readthedocs / en / latest / tutorials / embeddables.html
当使用值对象(我的情况下为CategoryType)表单提交的symfony表单(持续到DB)我得到以下警告
警告:ReflectionProperty :: getValue()期望参数1到给对象,字符串给定
这是因为symfony表单返回字符串而不是embeddable对象。
我现在唯一的解决方法是使用 mapped =>在中键入字段,然后在持久化之前在控制器操作中创建有效的可嵌入对象。但是这远远不是好的解决方案,我想避免这种情况。
我的实体,价值对象和表单(为了问题而简化)
Foo\BarBundle\Entity\CategoryType
<?php 命名空间Foo\BarBundle\Entity; class CategoryType { / ** * @var string * / protected $ value; public function __toString() { return(string)$ this-> getValue(); } / ** * @return string * / public function getValue() { return $这 - >值; } / ** * @param string $ value * * @return $ this * / public function setValue($ value) { $ this-> value = $ value; return $ this; } }Foo\BarBundle\Resources\\ \\ config \doctrine\CategoryType.orm.yml
CategoryType.orm.yml Foo \BarBundle\Entity\CategoryType: type:embeddable fields: value: type:stringFoo\BarBundle\Entity\Category
<?php 命名空间Foo\BarBundle\Entity; class类别 { / ** * @var整数 * / protected $ id; / ** * @var string * / protected $ name; / ** * @var类别类型 * / 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 $这个 * / public function setType($ type) { $ this-> type = $ type; return $ this; } / ** * @return string * / public function __toString() { return string)$ this-> getName(); } / ** * @return string * / public function getName() { return $这 - >名称; } / ** * @param string $ name * * @return $ this * / public function setName($ name) { $ this-> name = $ name; return $ this; } }Foo\BarBundle\Resources\\ \\ config \doctrine\Category.orm.yml
Foo\BarBundle\Entity\Category : type:entity fields: id: type:integer id:true 生成器:策略:AUTO 名称:类型:字符串嵌入:类型:类:类别类型Foo\BarBundle\Form\CategoryType
;?php 命名空间Foo\BarBundle\Form; 使用Symfony\Component\Form\AbstractType; 使用Symfony\Component\Form\FormBuilderInterface; 使用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('键入'); } / ** * @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; } }解决方案
教义嵌入行为只是一种持久化机制,所以它不能破坏独立于它的表单组件(并且与所有对象的图形一起使用)。
问题是您的表单设计不当(不符合您的对象图)。在这里,您有一个包装类别类别。因此,您的表单必须遵循与定义级别相同的结构。
您必须创建一个 CategoryTypeType 到你的 CategoryType 类),你添加一个值字段。然后,在 CategoryType (表单一)中,您必须为嵌入 CategoryTypeType 键入字段。
然后,表单组件将自动创建一个类别一个 CategoryType 。然后,Doctrine将简单地将您的对象保持为可嵌入,并且一切都将起作用:)
Has anyone encountered this problem when using doctrine embeddables and symfony forms?
if you don't know Doctrine Embeddables are, you can read about it here doctrine-orm.readthedocs/en/latest/tutorials/embeddables.html
When using value object (CategoryType in my case) with symfony form on form submission (during persisting to DB) I get the following warning
Warning: ReflectionProperty::getValue() expects parameter 1 to be object, string given
This happens because symfony form returns string instead of embeddable object.
The only workaround I have right now is to use mapped => false on type field and create valid embeddable object inside controller action just before persist. But that's far from "nice" solution and I want to avoid that.
My Entity, Value Object and form (simplified for the sake of question)
Foo\BarBundle\Entity\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; } }Foo\BarBundle\Resources\config\doctrine\CategoryType.orm.yml
CategoryType.orm.yml Foo\BarBundle\Entity\CategoryType: type: embeddable fields: value: type: stringFoo\BarBundle\Entity\Category
<?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; } }Foo\BarBundle\Resources\config\doctrine\Category.orm.yml
Foo\BarBundle\Entity\Category: type: entity fields: id: type: integer id: true generator: strategy: AUTO name: type: string embedded: type: class: CategoryTypeFoo\BarBundle\Form\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'; } }解决方案
The doctrine embedabble behavior is just a persistence mechanism, so, it can not break the form component which is independant from it (and works with all objects graph).
The issue is your form is not well designed (it does not follow your object graph). Here, you have a category which wraps a category type. So, your form must follow the same structure at the definition level.
You must create a CategoryTypeType form (mapped to your CategoryType class) where your add a value field. Then, in your CategoryType (the form one), you must embed the CategoryTypeType for the type field.
Then, the form component will automatically creates a Category which wraps a CategoryType. Then, Doctrine will simply persists your object as embeddable and everything will work :)
更多推荐
Doctrine Embeddables不能与Symfony表单一起使用
发布评论