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

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

概述我希望你能帮助我.我正在使用Symfony 2.x和Doctrine 2.x,我想创建一个由两个实体组成的表单.通过填写这一表格,我想将数据保存到两个学说实体. 为简单起见,我举了一个例子.多语种网上商店需要有英文和法文的名称和产品描述.我想用一个表单来创建一个新产品.此创建表单将包含Product实体(id; productTranslations; price,productTranslati 我希望你能帮助我.我正在使用Symfony 2.x和Doctrine 2.x,我想创建一个由两个实体组成的表单.通过填写这一表格,我想将数据保存到两个学说实体.

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

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

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

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

产品实体:

<?PHPnamespace 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实体:

<?PHPnamespace 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;    }}

产品类别:

<?PHPnamespace 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:

<?PHPnamespace 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的:

<?PHPnamespace 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 given500 Internal Server Error - ContextErrorException

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

更新1

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

ProductController的:

<?PHPnamespace 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 entitymanyToOne:      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的新版本吗?

总结

以上是内存溢出为你收集整理的表单 – Symfony2嵌入表单不会将数据持久保存到数据库全部内容,希望文章能够帮你解决表单 – Symfony2嵌入表单不会将数据持久保存到数据库所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1118356.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存