擾流:我想我找到了答案,但我不是100%確定;)Doctrine2:許多一對多在參考表的額外列(添加記錄)
我一直在尋找這question一段時間,但我無法設法使其工作。所以我創建實體假人測試的關係,在這裏,他們是:
- 一個
Product
可以在許多Cart
- 一個
Cart
可以包含幾個Product
- 在
Cart
的Product
是由訂單position
產品
<?php
namespace Acme\DemoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
* @ORM\Table(name="demo_product")
*/
class Product
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\OneToMany(targetEntity="CartHasProduct", mappedBy="product", cascade={"all"})
*/
protected $productCarts;
/**
* Constructor
*/
public function __construct()
{
$this->productCarts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Add productCarts
*
* @param \Acme\DemoBundle\Entity\CartHasProduct $productCarts
* @return Product
*/
public function addProductCart(\Acme\DemoBundle\Entity\CartHasProduct $productCarts)
{
$this->productCarts[] = $productCarts;
return $this;
}
/**
* Remove productCarts
*
* @param \Acme\DemoBundle\Entity\CartHasProduct $productCarts
*/
public function removeProductCart(\Acme\DemoBundle\Entity\CartHasProduct $productCarts)
{
$this->productCarts->removeElement($productCarts);
}
/**
* Get productCarts
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getProductCarts()
{
return $this->productCarts;
}
}
車
<?php
namespace Acme\DemoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
* @ORM\Table(name="demo_cart")
*/
class Cart
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\OneToMany(targetEntity="CartHasProduct", mappedBy="cart", cascade={"all"})
*/
protected $cartProducts;
/**
* Constructor
*/
public function __construct()
{
$this->cartProducts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Add cartProducts
*
* @param \Acme\DemoBundle\Entity\CartHasProduct $cartProducts
* @return Cart
*/
public function addCartProduct(\Acme\DemoBundle\Entity\CartHasProduct $cartProducts)
{
$this->cartProducts[] = $cartProducts;
return $this;
}
/**
* Remove cartProducts
*
* @param \Acme\DemoBundle\Entity\CartHasProduct $cartProducts
*/
public function removeCartProduct(\Acme\DemoBundle\Entity\CartHasProduct $cartProducts)
{
$this->cartProducts->removeElement($cartProducts);
}
/**
* Get cartProducts
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getCartProducts()
{
return $this->cartProducts;
}
}
最後CartHasProduct參考表
<?php
namespace Acme\DemoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
* @ORM\Table(name="demo_cartHasProduct")
*/
class CartHasProduct
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\ManyToOne(targetEntity="Cart", inversedBy="productCarts")
*/
protected $cart;
/**
* @ORM\ManyToOne(targetEntity="Product", inversedBy="cartProducts")
*/
protected $product;
/**
* @ORM\Column(type="integer")
*/
protected $position;
public function __construct(Cart $cart, Product $product, $position=0) {
$this->cart = $cart;
$this->product = $product;
$this->setPosition($position);
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set position
*
* @param integer $position
* @return CartHasProduct
*/
public function setPosition($position)
{
$this->position = $position;
return $this;
}
/**
* Get position
*
* @return integer
*/
public function getPosition()
{
return $this->position;
}
/**
* Set cart
*
* @param \Acme\DemoBundle\Entity\Cart $cart
* @return CartHasProduct
*/
public function setCart(\Acme\DemoBundle\Entity\Cart $cart = null)
{
$this->cart = $cart;
return $this;
}
/**
* Get cart
*
* @return \Acme\DemoBundle\Entity\Cart
*/
public function getCart()
{
return $this->cart;
}
/**
* Set product
*
* @param \Acme\DemoBundle\Entity\Product $product
* @return CartHasProduct
*/
public function setProduct(\Acme\DemoBundle\Entity\Product $product = null)
{
$this->product = $product;
return $this;
}
/**
* Get product
*
* @return \Acme\DemoBundle\Entity\Product
*/
public function getProduct()
{
return $this->product;
}
}
我已經手動創建該實體,加入@ORM註釋設置的關係,那麼我已使用app/console generate:doctrine:entities AcmeDemoBundle
來填充getter
,setter
和__construct
現在我控制器我有以下代碼:
<?php
namespace Acme\DemoBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class WelcomeController extends Controller
{
public function indexAction()
{
// Create a Cart Entity
$cart = new \Acme\DemoBundle\Entity\Cart();
// Create a Product Entity
$product = new \Acme\DemoBundle\Entity\Product();
// Add the Product into the Cart
$cart->getCartProducts()->add($product);
// Save the Cart
$em = $this->getDoctrine()->getManager();
$em->persist($cart);
$em->flush();
return $this->render('AcmeDemoBundle:Welcome:index.html.twig');
}
}
這樣做,我有以下的錯誤來了:
的關聯類型的Acme \ DemoBundle \實體\產品的找到實體ACME \ DemoBundle \實體\車#cartProducts,但期待的Acme \ DemoBundle \實體\ CartHasProduct
所以我的問題是如何增加一個產品成車?我是否需要手動創建關係對象(CartHasProduct
)?我會認爲主義會做到這一點。我到處看到Doctrine文檔,並且找不到與額外領域有關係的例子。
我也看過供應商的測試,有很多模型(非常有趣),但沒有關係中的額外領域。
我想在車中創造我自己的方法是這樣的:
public function addProduct(Product $product, $position=0) {
$relation = new CartHasProduct($this, $product, $position);
if (!$this->cartProducts->contains($relation)) {
$this->cartProducts->add($relation);
}
}
,但我想還是知道如果我需要實現它,如果它的意思是自動處理?
#### 更新1 ####
所以我最終將這種方法addProduct
。問題是未按預期工作。所以我試圖從Cart
中刪除所有Product
並添加一個新的。
這裏是我的功能刪除產品:
/**
* Reset the product for the cart
*
* @return bool
*/
public function resetCart() {
foreach ($this->getCartProducts() as $relation) {
$relation->getProduct()->removeProductCart($relation);
$this->removeCartProducts($relation);
}
}
,這裏是我怎麼稱呼它:
$em = $this->getDoctrine()->getManager();
$cart->resetCart();
$em->persist($cart);
$em->flush();
但記錄中沒有CartHasProduct表中刪除。
更新2我發現是什麼問題,你需要在OneTwoMany關係添加orphanRemoval=true
(在兩側),如果你想刪除的2個主要的實體之間(Cart
和Product
)的關係:
/**
* @ORM\Entity
* @ORM\Table(name="demo_product")
*/
class Product
{
...
/**
* @ORM\OneToMany(targetEntity="CartHasProduct", mappedBy="product", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $productCarts;
而且
/**
* @ORM\Entity
* @ORM\Table(name="demo_cart")
*/
class Cart
{
...
/**
* @ORM\OneToMany(targetEntity="CartHasProduct", mappedBy="cart", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $cartProducts;
...
/**
* Reset the product for the cart
*/
public function resetCart() {
$this->getCartProducts()->clear();
}
乾杯,
Maxime