ho entità Basket
e BasketItem
:Come a persistere un oggetto con molti oggetti correlati
/**
* Acme\BasketBundle\Entity\Basket
*
* @ORM\Entity(repositoryClass="Acme\BasketBundle\Repository\BasketRepository")
* @ORM\Table(name="orders")
* @ORM\HasLifecycleCallbacks()
*/
class Basket
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
// ...
/**
* @ORM\OneToMany(targetEntity="BasketItem", mappedBy="order_id",cascade={"all"})
*/
protected $items;
// ...
public function __construct() {
$this->items = new ArrayCollection();
}
/**
* Add item
*
* @param BasketItem $item
*/
public function addItem(BasketItem $item)
{
$key = $this->find($item->getProduct()->getId());
if ($key === false) {
$this->items->add($item);
} else {
$this->items->get($key)->raiseQuantity($item->getQuantity());
}
}
/**
* Find an item (if present)
*
* @param integer $id
* @return integer
*/
public function find($id)
{
foreach ($this->items as $key => $item) {
if ($item->getProduct()->getId() == $id)
return $key;
}
return false;
}
}
/**
* Acme\BasketBundle\Entity\BasketItem
*
* @ORM\Entity
* @ORM\Table(name="order_items")
*/
class BasketItem
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
// ...
/**
* @ORM\ManyToOne(targetEntity="Basket", inversedBy="items")
* @ORM\JoinColumn(name="order_id", referencedColumnName="id")
*/
private $basket;
// ...
}
Ora, quando creo un cesto e riempirlo con oggetti, io avere problemi a persistere nel db.
In seguito non funziona come previsto.
$basket = new Basket();
$basket->addItem(new BasketItem($product1, 1));
$basket->addItem(new BasketItem($product2, 2));
$em->persist($basket);
$em->flush();
poi ho provato a seguito della manual più da vicino:
$basket = new Basket();
$basket->addItem(new BasketItem($product1, 1));
$basket->addItem(new BasketItem($product2, 2));
$em->persist($basket);
foreach ($basket->getItems() as $item) {
$em->persist($item);
}
$em->flush();
Che non ha funzionato come previsto nessuno dei due.
In entrambi i casi tutti i dati viene salvato nel database ma gli elementi paniere non sono legati a canestro, vale a dire order_id
dell'entità BasketItem
è NULL
.
Qualcuno può spiegarmi cosa sto facendo male, per favore? Si prega di notare che sono nuovo di Doctrine. Grazie!
EDIT:
Sono davvero confuso già. Ecco la mia prova semplificata:
<?php
namespace Amsel\BasketBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Amsel\BasketBundle\Entity\Basket
*
* @ORM\Entity(repositoryClass="Amsel\BasketBundle\Repository\BasketRepository")
* @ORM\Table(name="orders")
*/
class Basket
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var ArrayCollection $items
*
* @ORM\OneToMany(targetEntity="BasketItem", mappedBy="basket", cascade={"all"})
*/
protected $items;
public function __construct() {
$this->items = new ArrayCollection();
}
/**
* Add item
*
* @param BasketItem $item
*/
public function addItem(BasketItem $item)
{
$this->items->add($item);
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Get items
*
* @return Doctrine\Common\Collections\Collection
*/
public function getItems()
{
return $this->items;
}
}
<?php
namespace Amsel\BasketBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Amsel\BasketBundle\Entity\BasketItem
*
* @ORM\Entity(repositoryClass="Amsel\BasketBundle\Repository\BasketItemRepository")
* @ORM\Table(name="order_items")
*/
class BasketItem
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var Basket $basket
*
* @ORM\ManyToOne(targetEntity="Basket", inversedBy="items")
* @ORM\JoinColumn(name="order_id", referencedColumnName="id")
*/
protected $basket;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set basket
*
* @param Amsel\BasketBundle\Entity\Basket $basket
*/
public function setBasket(\Amsel\BasketBundle\Entity\Basket $basket)
{
$this->basket = $basket;
}
/**
* Get basket
*
* @return Amsel\BasketBundle\Entity\Basket
*/
public function getBasket()
{
return $this->basket;
}
}
public function testAction(Request $request) {
$em = $this->getDoctrine()->getEntityManager();
$basket = new Basket();
$basket->addItem(new BasketItem());
$basket->addItem(new BasketItem());
$em->persist($basket);
try {
$em->flush();
} catch(Exception $e) {
die('ERROR: '.$e->getMessage());
}
die ('end');
}
Ma ancora - gli articoli di ordine (BasketItem
) vengono memorizzati, ma sono non legato all'ordine (Basket
).
Can pubblichi il contenuto della tua funzione addItem? Fa internamente $ this-> items-> add ($ item); ? Il resto sembra ok .. –
@Kees Schepers, grazie per la tua risposta! Ho aggiunto il metodo 'addItem' (e' find'). Se il resto è ok, sono davvero perso - altre idee che cosa potrei provare? – Czechnology
Ho avuto qualche problema simile qualche tempo fa, specifichi il tuo campo $ order_id nella tua classe BasketItem forse? Perché questo può causare questi problemi. Se dubiti di poter postare la tua intera classe di entità basketitem. Il mio amico ha parlato di questo con me: http://pietervogelaar.nl/doctrine-2-use-foreign-key-as-field-in-dql/ –