Doctrine Embeddables不能与Symfony表单一起使用 [英] Doctrine Embeddables not working with Symfony forms

查看:99
本文介绍了Doctrine Embeddables不能与Symfony表单一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


如果你不知道Doctrine Embeddables是,你可以在这里阅读这里
http://doctrine-orm.readthedocs .org / 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: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?

if you don't know Doctrine Embeddables are, you can read about it here http://doctrine-orm.readthedocs.org/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: 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表单一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆