问题描述
当使用值对象(我的情况下为CategoryType)表单提交的symfony表单(持续到DB)我得到以下警告
这是因为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:string
Foo\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?
When using value object (CategoryType in my case) with symfony form on form submission (during persisting to DB) I get the following warning
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: string
Foo\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: CategoryType
Foo\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表单一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!