为简单起见,我举了一个例子.多语种网上商店需要有英文和法文的名称和产品描述.我想用一个表单来创建一个新产品.此创建表单将包含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嵌入表单不会将数据持久保存到数据库所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)