表单 – Symfony2嵌入表单不会将数据持久保存到数据库

我希望你能帮助我.我正在使用Symfony 2.x和Doctrine 2.x,我想创建一个由两个实体组成的表单.通过填写这一表格,我想将数据保存到两个学说实体.

为简单起见,我举了一个例子.多语种网上商店需要有英文和法文的名称和产品描述.我想用一个表单来创建一个新产品.此创建表单将包含Product实体(id; productTranslations; price,productTranslations)以及ProductTranslation实体(id; name; description; language,product)中的数据.生成的创建产品表单包含以下字段(名称;描述;语言(EN / FR);价格).

Product和ProductTranslation实体通过双向一对多关系相互关联.关系的拥有站点是ProductTranslation.

提交表单后,我希望将数据持久保存到两个实体(Product和ProductTranslation).这是出错的地方.我不能坚持这些数据.

因此,我尝试了以下内容:

产品实体:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Product
 *
 * @ORM\Table(name="product")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\ProductRepository")
 */
class Product
{   
    /**
     * @var int
     *
     * @ORM\Column(name="id",type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="price",type="decimal",precision=10,scale=0)
     */
    private $price;

    /**
     * @ORM\OneToMany(targetEntity="AppBundle\Entity\ProductTranslation",mappedBy="product")
     */
    private $productTranslations;

    public function __construct()
    {
        $this->productTranslations = new ArrayCollection();
    }  

    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set price
     *
     * @param string $price
     *
     * @return Product
     */
    public function setPrice($price)
    {
        $this->price = $price;

        return $this;
    }

    /**
     * Get price
     *
     * @return string
     */
    public function getPrice()
    {
        return $this->price;
    }

    /**
     * Set productTranslations
     *
     * @param \stdClass $productTranslations
     *
     * @return Product
     */
    public function setProductTranslations($productTranslations)
    {
        $this->productTranslations = $productTranslations;

        return $this;
    }

    /**
     * Get productTranslations
     *
     * @return \stdClass
     */
    public function getProductTranslations()
    {
        return $this->productTranslations;
    }

    /**
     * Add productTranslation
     *
     * @param \AppBundle\Entity\ProductTranslation $productTranslation
     *
     * @return Product
     */
    public function addProductTranslation(\AppBundle\Entity\ProductTranslation $productTranslation)
    {
        $this->productTranslations[] = $productTranslation;

        return $this;
    }

    /**
     * Remove productTranslation
     *
     * @param \AppBundle\Entity\ProductTranslation $productTranslation
     */
    public function removeProductTranslation(\AppBundle\Entity\ProductTranslation $productTranslation)
    {
        $this->productTranslations->removeElement($productTranslation);
    }
}

ProductTranslation实体:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * ProductTranslation
 *
 * @ORM\Table(name="product_translation")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\ProductTranslationRepository")
 */
class ProductTranslation
{
    /**
     * @var int
     *
     * @ORM\Column(name="id",type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name",type="string",length=255)
     */
    private $name;

    /**
     * @var string
     *
     * @ORM\Column(name="description",type="text")
     */
    private $description;

    /**
     * @var string
     *
     * @ORM\Column(name="language",length=5)
     */
    private $language;

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Product",inversedBy="productTranslations",cascade={"persist"})
     * @ORM\JoinColumn(name="product_translation_id",referencedColumnName="id")
     * 
     */
    private $product;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     *
     * @return ProductTranslation
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set description
     *
     * @param string $description
     *
     * @return ProductTranslation
     */
    public function setDescription($description)
    {
        $this->description = $description;

        return $this;
    }

    /**
     * Get description
     *
     * @return string
     */
    public function getDescription()
    {
        return $this->description;
    }

    /**
     * Set language
     *
     * @param string $language
     *
     * @return ProductTranslation
     */
    public function setLanguage($language)
    {
        $this->language = $language;

        return $this;
    }

    /**
     * Get language
     *
     * @return string
     */
    public function getLanguage()
    {
        return $this->language;
    }

    /**
     * Set product
     *
     * @param \AppBundle\Entity\Product $product
     *
     * @return ProductTranslation
     */
    public function setProduct(\AppBundle\Entity\Product $product = null)
    {
        $this->product = $product;

        return $this;
    }

    /**
     * Get product
     *
     * @return \AppBundle\Entity\Product
     */
    public function getProduct()
    {
        return $this->product;
    }
}

产品类别:

<?php

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;

class ProductType extends AbstractType {

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder,array $options) {
        $builder->add('productTranslations',ProductTranslationType::class,array('label' => false,'data_class' => null));
        $builder
                ->add('price',MoneyType::class)
        ;
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver) {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Product'
        ));
    }

}

ProductTranslationType:

<?php

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;

class ProductTranslationType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder,array $options)
    {
        $builder
            ->add('name',TextType::class)
            ->add('description',TextareaType::class )
            ->add('language',ChoiceType::class,array('choices' => array('en' => 'EN','fr' => 'FR')))
        ;
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\ProductTranslation'
        ));
    }
}

ProductController的:

<?php

namespace AppBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use AppBundle\Entity\Product;
use AppBundle\Form\ProductType;
use AppBundle\Entity\ProductTranslation;

/**
 * Product controller.
 *
 */
class ProductController extends Controller {

    /**
     * Creates a new Product entity.
     *
     */
    public function newAction(Request $request) {
        $em = $this->getDoctrine()->getManager();
        $product = new Product();

        $productTranslation = new ProductTranslation();

        $form = $this->createForm('AppBundle\Form\ProductType',$product);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();

            $product->getProductTranslations()->add($product);

            $productTranslation->setProduct($product);   

            $em->persist($productTranslation);
            $em->flush();

            return $this->redirectToRoute('product_show',array('id' => $product->getId()));
        }

        return $this->render('product/new.html.twig',array(
                    'product' => $product,'form' => $form->createView(),));
    }
}

错误:

Warning: spl_object_hash() expects parameter 1 to be object,string given
500 Internal Server Error - ContextErrorException

我看了一下食谱的帮助:http://symfony.com/doc/current/book/forms.html#embedded-forms,但我一直无法使它工作.

更新1

我还没有找到问题的答案.根据下面的评论,我看了一下这些协会.我已经对ProductController进行了调整,这使我能够测试数据是否以正确的方式插入数据库中.数据已正确插入,但我无法通过表单插入.希望有人可以帮助我.

ProductController的:

<?php

namespace AppBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

use AppBundle\Entity\Product;
use AppBundle\Form\ProductType;

/**
 * Creates a new Product entity.
 *
 */
public function newAction(Request $request) {
    $em = $this->getDoctrine()->getManager();
    $product = new Product();

    $productTranslation = new ProductTranslation();

    /* Sample data insertion */
    $productTranslation->setProduct($product);
    $productTranslation->setName('Product Q');
    $productTranslation->setDescription('This is product Q');
    $productTranslation->setLanguage('EN');

    $product->setPrice(95);
    $product->addProductTranslation($productTranslation);

    $em->persist($product);
    $em->persist($productTranslation);
    $em->flush();
    /* End sample data insertion */

    $form = $this->createForm('AppBundle\Form\ProductType',$product);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $em = $this->getDoctrine()->getManager();

        $product->getProductTranslations()->add($product);

        $productTranslation->setProduct($product);   

        $em->persist($productTranslation);
        $em->flush();

        return $this->redirectToRoute('product_show',array('id' => $product->getId()));
    }

    return $this->render('product/new.html.twig',array(
                'product' => $product,));
}

我现在收到以下错误消息:

Expected value of type "Doctrine\Common\Collections\Collection|array" for association field "AppBundle\Entity\Product#$productTranslations",got "string" instead.

更新2

在持久化数据之前,ProductController newAction中的变量product的var_dump()显示:

object(AppBundle\Entity\Product)[493]
  private 'id' => null
  private 'price' => float 3
  private 'productTranslations' => 
    object(Doctrine\Common\Collections\ArrayCollection)[494]
      private 'elements' => 
        array (size=4)
          'name' => string 'abc' (length=45)
          'description' => string 'alphabet' (length=35)
          'language' => string 'en' (length=2)
          0 => 
            object(AppBundle\Entity\ProductTranslation)[495]
              ...

解决方法

错误是自我解释; productTranslations必须是Array或arrayCollection.这是一个“字符串”.

所以在Product的构造函数中:

public function __construct()
{
    $this->activityTranslations = new ArrayCollection();
    $this->productTranslations = new \Doctrine\Common\Collections\ArrayCollection();
}

对于setter / getter,您可以使用:

public function addProductTranslation(AppBundle\Entity\ProductTranslation $pt)
{
    $this->productTranslations[] = $pt;
    $pt->setProduct($this);
    return $this;
}


public function removeProductTranslation(AppBundle\Entity\ProductTranslation  $pt)
{
    $this->productTranslations->removeElement($pt);
}

public function getProductTranslations()
{
    return $this->productTranslations;
}

编辑:
在使用Symfony2.3的YAML中,这是我正在使用的对象映射配置(强调应该添加级联持久性的地方).

//Product entity 
oneToMany:
      productTranslations:
        mappedBy: product
        targetEntity: App\Bundle\...Bundle\Entity\ProductTranslation
        cascade:      [persist]

// ProductTranslation entity
manyToOne:
      product:
        targetEntity: App\Bundle\..Bundle\Entity\Product
        inversedBy: productTranslations
        joinColumn:
          name: product_id
          type: integer
          referencedColumnName: id
          onDelete: cascade

另请注意,您不需要在Product实体中使用setProductTranslation()setter,因为添加和删除目标是替换它.

EDIT2:

在Symfony2中,以下是我处理带有集合的表单的方法:

class ProductType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder,array $options)
        {
            $builder
                ->add('productPrice','number',array('required' => false))
                ->add('productTranslations','collection',array(
                    'type' => new ProducatTranslationType()

                    ))

            ;

        }

我不知道为什么你没有在formType中指定集合.它是Symfony的新版本吗?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


HTML代码中要想改变字体颜色,常常需要使用CSS样式表。CSS是一门用来描述网页上样式的语言,通过编写CSS代码可以实现网页中各元素的大小、颜色、字体等各种样式的控制。那么如何在HTML代码中应用CSS样式来改变字体颜色呢?这里为大家介绍一下。 首先,在HTML代码...
HTML代码如何让字体盖住图片呢?需要使用CSS的position属性及z-index属性。 img { position: relative; z-index: -1; } p { position: absolute; to...
HTML代码字体设置 在HTML中,我们可以使用标签来设置网页中的文字字体。常用的字体标签是font和style,下面我们来学习如何使用这些标签。 1. font标签 使用font标签可以改变文字的字体、颜色和大小。它有三个属性font-family、color和...
在网页设计中,HTML代码的字体和字号选择是非常重要的一个环节,因为它们直接关系到页面的可读性和视觉效果。 要指定文本的字体和字号,可以使用HTML中的样式属性。使用样式属性设置字体和字号,如下所示: <p style="font-family: Aria...
HTML(Hypertext Markup Language,超文本标记语言)是一种用于创建网页的标准语言。它由许多标签(一对尖括号包围的关键字)组成,这些标签告诉浏览器如何显示内容。使用HTML代码,我们可以轻松地创建各种类型的图像和图形,如太极图。 在HTM...
外链是指在一个网页中添加一个指向其他网站的链接,用户可以通过这个链接直接跳转到其他网站。在HTML中,实现外链的方法很简单,只需要使用标签就可以了。 <a href="http://www.example.com">这是一个外链,点击跳转到www.ex...
HTML代码是实现网页界面的基础,而网页中的各种表单则是用户和网站进行交互的重要方式之一。下面我们来介绍如何使用HTML代码实现一个简单的报名表格。 <form action="submit.php" method="post"> &lt...
HTML是一种标记语言,用于开发网站和其他互联网内容。字体是网站设计中的关键元素之一,它可以决定网站的整体风格和呈现效果。HTML提供了字体编辑器,使网站设计变得更加容易。 <font face="Arial"> 这里是Arial字体 &...
HTML代码中,字体样式是开发者们必备的一部分。在HTML中,我们可以通过特定的标签和属性设置字体的样式、颜色和大小,以达到更好的排版效果。 <p style="font-size: 14px; color: #333; font-family:...
HTML中的字体可以设为粗体,以强调文本信息。我们可以通过使用一些标签来实现这一功能。其中,常用的标签包括: 1. 标签:该标签会把文本加粗显示,语法如下: 这是一段加粗的文本 2. 标签:与标签作用相同,但语义更强,表示该文本内容的重要性。语法如下:...
HTML代码可以实现文件的上传和下载,在网页开发中相当常见。通过使用<input>标签和<form>标签,我们可以轻松创建一个文件上传表单。 <form action="upload.php" method="post" enct...
HTML代码非常常见于网页设计中。在一些需要处理时间相关数据的场景下,可能需要将时间戳转换为实际时间,这时候就需要使用一些特定的HTML代码。 function timeStamp2Time(time){ var date = new Date(time...
HTML是一种用于创建网页的标记语言。在HTML中,我们可以使用超链接标签实现下载文件到本地的功能。 具体实现步骤如下: <a href="文件的URL" download="文件名">下载文件</a> 其中,href属性是文件...
在HTML代码中,对于字体靠左对齐有各种方法。其中最简单的方式之一是使用pre标签。 使用pre标签可以保留一段文本中的空格和换行符,从而使代码排版更加整齐。下面是一个例子: <p>这是一个段落。</p> &lt...
HTML代码字典是一本解释HTML标记和属性的参考文献。这本字典中包含了最常用的HTML代码以及它们的属性和值的详细描述。 例如,以下是HTML代码字典中的一部分内容: <a href="url">link text</a> 在...
在网页开发过程中,遇到一些需要用户复制的内容,我们通常都会提供复制按钮,让用户更方便地复制所需内容。下面我们来介绍如何使用html代码实现一键复制的功能。 var copyBtn = document.querySelector('#copy-bt...
用户登录 欢迎来到公司登录界面,请输入用户名和密码登录 用户名: 密码: 代码解释: 第1行:定义了一个 HTML 文档 第2行:开始了 HTML 头部 第3行:定义了...
HTML 代码是用来创建网页的语言,它包含了许多不同的元素和属性,让我们可以在网页中添加各种不同的元素和内容,如文字、图片、链接等等。在编写 HTML 代码时,我们可以使用各种不同的样式来美化我们的网页,例如更改字体、颜色、大小等等。 font-family:...
HTML代码中的字体转移 在编写HTML代码时,我们经常会使用各种字体来增强页面的可读性和视觉效果。但是,有些字符或特殊符号可能会在HTML中具有不同的含义,这就需要使用字体转义转换成HTML可以正常显示的字符。 在HTML中,使用"&"符号表示一个特殊字符将要被转...
HTML 编程语言中,你可以使用字体属性来更改文本的字体大小、颜色和样式。其中,字体颜色是最常用的样式更改。在 HTML 中,你可以使用 "color" 属性来更改文本的颜色。下面是一个使用 "pre" 标签的代码示例,演示如何使用 "color" 属性来更改字体颜色...