我正在尝试创建两个实体之间的OneToOne单向关系。我已经创建了模式,但是当我提交表单时,它没有将数据持久化到集合中。根据我所有的研究,我怀疑这是因为我没有正确设置拥有的实体,但我已经尝试了所有我能找到的方法,但没有运气。
Entity - Products.php (owner Side)
<?php
namespace SCWDesignsBundleEntityProducts;
use DoctrineORMMapping as ORM;
use DoctrineCommonCollectionsArrayCollection;
use SymfonyComponentValidatorMappingClassMetaData;
use SymfonyComponentValidatorConstraints as Assert;
/**
* @ORMEntity(repositoryClass="SCWDesignsBundleEntityRepositoryProductsProductRespository")
* @ORMTable(name="products")
*/
class Products {
/**
* @ORMID
* @ORMColumn(type="integer")
* @ORMGeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORMManyToOne(targetEntity="ProductCategories")
* @ORMJoinColumn(name="category_id", referencedColumnName="id")
* @AssertNotBlank()
*/
protected $category_id;
/**
* @ORMColumn(type="boolean", options={"default" = 0})
*/
protected $featured;
/**
* @ORMColumn(type="boolean", options={"default" = 1})
*/
protected $enabled;
/**
* @ORMColumn(type="boolean", options={"default" = 0})
*/
protected $free_shipping;
/**
* @ORMOneToOne(targetEntity="ProductSales")
* @ORMJoinColumn(name="participate_sale", referencedColumnName="id")
*/
protected $participate_sale;
/**
* @ORMColumn(type="decimal")
*/
protected $price;
/**
* @ORMColumn(type="integer")
*/
protected $sku;
/**
* @ORMColumn(type="datetime")
*/
protected $arrival_date;
/**
* @ORMColumn(type="datetime")
*/
protected $update_date;
/*
* ArrayCollection for ProductDescription
* @ORMOneToOne(targetEntity="ProductDescription", mappedBy="product_id", cascade={"persist"})
* @ORMJoinColumn(name="description", referencedColumnName="product_id")
*/
protected $description;
public function __construct() {
$this->setArrivalDate(new DateTime());
$this->description = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId() {
return $this->id;
}
/**
* Set featured
*
* @param boolean $featured
* @return Products
*/
public function setFeatured($featured) {
$this->featured = $featured;
return $this;
}
/**
* Get featured
*
* @return boolean
*/
public function getFeatured() {
return $this->featured;
}
/**
* Set enabled
*
* @param boolean $enabled
* @return Products
*/
public function setEnabled($enabled) {
$this->enabled = $enabled;
return $this;
}
/**
* Get enabled
*
* @return boolean
*/
public function getEnabled() {
return $this->enabled;
}
/**
* Set free_shipping
*
* @param boolean $freeShipping
* @return Products
*/
public function setFreeShipping($freeShipping) {
$this->free_shipping = $freeShipping;
return $this;
}
/**
* Get free_shipping
*
* @return boolean
*/
public function getFreeShipping() {
return $this->free_shipping;
}
/**
* Set price
*
* @param string $price
* @return Products
*/
public function setPrice($price) {
$this->price = $price;
return $this;
}
/**
* Get price
*
* @return string
*/
public function getPrice() {
return $this->price;
}
/**
* Set sku
*
* @param integer $sku
* @return Products
*/
public function setSku($sku) {
$this->sku = $sku;
return $this;
}
/**
* Get sku
*
* @return integer
*/
public function getSku() {
return $this->sku;
}
/**
* Set arrival_date
*
* @param DateTime $arrivalDate
* @return Products
*/
public function setArrivalDate($arrivalDate) {
$this->arrival_date = $arrivalDate;
return $this;
}
/**
* Get arrival_date
*
* @return DateTime
*/
public function getArrivalDate() {
return $this->arrival_date;
}
/**
* Set update_date
*
* @param DateTime $updateDate
* @return Products
*/
public function setUpdateDate($updateDate) {
$this->update_date = $updateDate;
return $this;
}
/**
* Get update_date
*
* @return DateTime
*/
public function getUpdateDate() {
return $this->update_date;
}
/**
* Set category_id
*
* @param SCWDesignsBundleEntityProductsProductCategories $categoryId
* @return Products
*/
public function setCategoryId(SCWDesignsBundleEntityProductsProductCategories $categoryId = null) {
$this->category_id = $categoryId;
return $this;
}
/**
* Get category_id
*
* @return SCWDesignsBundleEntityProductsProductCategories
*/
public function getCategoryId() {
return $this->category_id;
}
/**
* Set participate_sale
*
* @param SCWDesignsBundleEntityProductsProductSales $participateSale
* @return Products
*/
public function setParticipateSale(SCWDesignsBundleEntityProductsProductSales $participateSale = null) {
$this->participate_sale = $participateSale;
return $this;
}
/**
* Get participate_sale
*
* @return SCWDesignsBundleEntityProductsProductSales
*/
public function getParticipateSale() {
return $this->participate_sale;
}
/**
* Set description
*
* @param SCWDesignsBundleEntityProductsProductDescrition $description
* @return Products
*/
public function setDescription($description) {
$this->description = $description;
return $this;
}
/**
* Get description
*
* @return string
*/
public function getDescription() {
return $this->description;
}
}
Entity - ProductDescription.php
<?php
namespace SCWDesignsBundleEntityProducts;
use DoctrineORMMapping as ORM;
use SCWDesignsBundleEntityBaseEntity;
use SymfonyComponentValidatorMappingClassMetaData;
use SymfonyComponentValidatorConstraints as Assert;
/**
* @ORMEntity
* @ORMTable(name="product_description")
*/
class ProductDescription extends BaseEntity {
/**
* @ORMManyToOne(targetEntity="Products")
* @ORMJoinColumn(name="product_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $product_id;
/**
* @ORMColumn(type="string", columnDefinition="VARCHAR(255)")
* @AssertLength(
* min = 2,
* max = 255,
* minMessage = "The item name must be at least {{ limit }} characters long.",
* maxMessage = "The item name cannot be longer than {{ limit }} characters."
* )
* @AssertNotBlank()
*/
protected $name;
/**
* @ORMColumn(type="text")
* @AssertNotBlank()
*/
protected $brief_description;
/**
* @ORMColumn(type="text")
* @AssertNotBlank()
*/
protected $full_description;
/**
* @ORMColumn(type="string", columnDefinition="VARCHAR(255)")
* @AssertLength(
* min = 2,
* max = 255,
* minMessage = "The tags characters must be at least {{ limit }} characters long.",
* maxMessage = "The tags characters cannot be longer than {{ limit }} characters."
* )
* @AssertNotBlank()
*/
protected $meta_tags;
/**
* @ORMColumn(type="string", columnDefinition="VARCHAR(255)")
* @AssertLength(
* min = 2,
* max = 255,
* minMessage = "The tags title must be at least {{ limit }} characters long.",
* maxMessage = "The tags title cannot be longer than {{ limit }} characters."
* )
* @AssertNotBlank()
*/
protected $meta_title;
/**
* @ORMColumn(type="text")
* @AssertNotBlank()
*/
protected $meta_description;
/**
* Set name
*
* @param string $name
* @return ProductDescription
*/
public function setName($name) {
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName() {
return $this->name;
}
/**
* Set brief_description
*
* @param string $briefDescription
* @return ProductDescription
*/
public function setBriefDescription($briefDescription) {
$this->brief_description = $briefDescription;
return $this;
}
/**
* Get brief_description
*
* @return string
*/
public function getBriefDescription() {
return $this->brief_description;
}
/**
* Set full_description
*
* @param string $fullDescription
* @return ProductDescription
*/
public function setFullDescription($fullDescription) {
$this->full_description = $fullDescription;
return $this;
}
/**
* Get full_description
*
* @return string
*/
public function getFullDescription() {
return $this->full_description;
}
/**
* Set meta_tags
*
* @param string $metaTags
* @return ProductDescription
*/
public function setMetaTags($metaTags) {
$this->meta_tags = $metaTags;
return $this;
}
/**
* Get meta_tags
*
* @return string
*/
public function getMetaTags() {
return $this->meta_tags;
}
/**
* Set meta_title
*
* @param string $metaTitle
* @return ProductDescription
*/
public function setMetaTitle($metaTitle) {
$this->meta_title = $metaTitle;
return $this;
}
/**
* Get meta_title
*
* @return string
*/
public function getMetaTitle() {
return $this->meta_title;
}
/**
* Set meta_description
*
* @param string $metaDescription
* @return ProductDescription
*/
public function setMetaDescription($metaDescription) {
$this->meta_description = $metaDescription;
return $this;
}
/**
* Get meta_description
*
* @return string
*/
public function getMetaDescription() {
return $this->meta_description;
}
/**
* Get id
*
* @return integer
*/
public function getId() {
return $this->id;
}
/**
* Set product_id
*
* @param SCWDesignsBundleEntityProductsProducts $productId
* @return ProductDescription
*/
public function setProductId(SCWDesignsBundleEntityProductsProducts $productId = null) {
$this->product_id = $productId;
return $this;
}
/**
* Get product_id
*
* @return SCWDesignsBundleEntityProductsProducts
*/
public function getProductId() {
return $this->product_id;
}
}
FormType - NewProductFormType.php
<?php
namespace SCWDesignsBundleFormAdmin;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolverInterface;
use SCWDesignsBundleFormTypesProductDescriptionType;
class NewProductFormType extends AbstractType {
private $entityManager;
public function __construct($entityManager) {
$this->entityManager = $entityManager;
}
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('featured', 'checkbox', array('label' => 'Featured', 'required' => false))
->add('enabled', 'checkbox', array('label' => 'Enabled', 'required' => false))
->add('freeshipping', 'checkbox', array('label' => 'Free Shipping', 'required' => false))
// ->add('participate_sale', 'checkbox', array('label' => 'Sale', 'required' => false))
->add('price', 'text', array('label' => 'Price', 'required' => true))
->add('sku', 'text', array('label' => 'Sku', 'required' => false))
->add('description', 'collection', array(
'type' => new ProductDescriptionType(),
'allow_add' => true,
'by_reference' => true
))
->add('category_id', 'entity', array(
'class' => 'SCWDesignsBundle:ProductsProductCategories',
'property' => 'name',
'placeholder' => false
));
}
public function getName() {
return 'product_new';
}
}
Type - ProductDescriptionType.php
<?php
namespace SCWDesignsBundleFormTypes;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolverInterface;
class ProductDescriptionType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('name', null, array('label' => 'Product Name', 'required' => true))
->add('full_description', 'textarea', array('label' => 'Full Description', 'required' => false))
->add('brief_description', 'textarea', array('label' => 'Brief Description', 'required' => false))
->add('meta_tags', null, array('label' => 'Meta Tags', 'required' => false))
->add('meta_title', null, array('label' => 'Meta Title', 'required' => false))
->add('meta_description', 'text', array('label' => 'Meta Description', 'required' => false));
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array('data_class' => 'SCWDesignsBundleEntityProductsProductDescription'));
}
public function getName() {
return 'product_description';
}
}
Controller - ProductsController.php
public function addProductAction(Request $request) {
$categories = $this->getCategories();
$em = $this->getDoctrine()->getEntityManager();
$product = new Products();
$form = $this->createForm(new NewProductFormType($em), $product);
$form->handleRequest($request);
if ($form->isValid()) {
$date = new DateTime('NOW');
$product->setUpdateDate($date);
$em->persist($product);
$em->flush();
return $this->redirect($this->generateUrl('scw_designs_admin_products'));
}
return $this->render('SCWDesignsBundle:AdminProductsActions:new.html.twig', array(
'active_page' => 'products',
'categories' => $categories,
'form' => $form->createView(),
'action' => $this->generateUrl('scw_designs_admin_products_new')
));
}
由于这让我很伤心,我决定在与sshaun和ddproxy一起工作后,在官方#symfony irc频道中发布我的答案。
首先,我确实把所有权关系搞错了。需要将逆函数切换到product.php。其次,我需要保存数据,所以我将下面的内容添加到控制器中,瞧,就像变魔术一样,它起作用了。
if ($form->isValid()) {
$date = new DateTime('NOW');
$product->setUpdateDate($date);
$em->persist($product);
$em->flush();
$description = $product->getDescription()->first();
$description->setProductId($product);
$em->persist($description);
$em->flush();
return $this->redirect($this->generateUrl('scw_designs_admin_products'));
}