도와 주시면 감사하겠습니다. Symfony 2.x와 Doctrine 2.x을 사용하고 있으며 양식을 하나 만들고 싶습니다. 두 개의 엔티티로 구성되어 있습니다. 이 양식을 작성하여 데이터를 두 개의 교리 실체에 보관하고 싶습니다.Symfony2 임베디드 양식이 데이터를 데이터베이스에 저장하지 않습니다.
간단히하기 위해 예제를 만들었습니다. 다국어 웹샵은 영어와 프랑스어로 이름과 제품 설명이 필요합니다. 한 가지 양식을 사용하여 새 제품을 만들고 싶습니다. 이 생성 양식에는 Product 엔터티 (id, productTranslations, price, productTranslations)의 데이터와 ProductTranslation 엔터티 (ID, 이름, 설명, 언어, 제품)의 데이터가 포함됩니다. 결과 제품 작성 양식에는 다음 필드 (이름, 설명, 언어 (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", type="string", 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;
}
}
ProductType :
Thusfar, 나는 다음을 시도
<?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,
'form' => $form->createView(),
));
}
:
Expected value of type "Doctrine\Common\Collections\Collection|array" for association field "AppBundle\Entity\Product#$productTranslations", got "string" instead.
업데이트를 2
ProductController newAction에서 변수 제품에서 위해 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]
...
먼저 엔터티 매핑을 수정해야합니다. http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/association-mapping.html 및 올바른 연결 관리 방법 설정 http : // doctrine -orm.readthedocs.io/projects/doctrine-orm/ko/latest/reference/working-with-associations.html 컨트롤러에서 번역 된 제품을 유지하려고 시도하는 것보다 더 효과적입니다. – 1ed
@ 1ed 나는 ProductTranslation 엔티티로 만든 실수를 언급했다고 생각합니다. 제품에 다 대일 주석을 추가하는 것을 잊어 버렸습니다. 그러나 그 결과는 여전히 동일합니다. –
매핑을 변경 했습니까? 그렇다면'php app/console doctrine : schema : update --force'를 실행해야합니다. 그렇지 않으면 다른 제안이 없습니다. 오류 메시지가 많이 표시되지 않습니다. URL에 "app_dev.php"를 사용하면 어떻게됩니까? –