I have a many-to-many relationship between two tables: Products and Orders.
Doctrine then generates a third table. Until then calm down.
But I wanted to generate in this third table more fields (qtde and unit value at the time of purchase).
The question is: How do I make this relationship work in Doctrine (with annotations right in the Entities) and how do I pick up the quantity and value of a given product table)?
The closest of an explanation I found was this:
But there is no explanation of how the ArrayCollection works for cases like this and how to get or set the extra fields in the third table.
Thanks in advance for all the help you can give.
Table Products (Table 1)
Id (pk)
Name
Value
Orders table (Table 2)
Id (pk)
TotalValue
Table ProductsOrders (Insetting Table)
Product (fk)
Order (fk)
Quantity
UnityValue
-
Entities
Below are the entities made according to instructions. Note, however, that the correct method of working with the extra - i columns is missing. and how to get EntityManager to take the extra columns of the ProductOrder entity (through of course the link fields in Product entities and < strong> Order ).
It is also important information on how to proceed to make the relationship of this third table with another, since it does not have a proper ID, since the ID is formed by the set of Product ID + Order ID.
<?php
/**
* @Entity(repositoryClass="Repositories\ProductRepository")
* @Table(name="Products")
*/
class Product
{
/**
* @Id
* @Column(type="integer")
* @GeneratedValue
*/
protected $id;
/**
* @Column(length=100)
*/
protected $name;
/**
* @Column(type="decimal", precision=10, scale=2)
*/
protected $value;
/**
* @OneToMany(targetEntity="ProductOrder", mappedBy="product")
*/
protected $orders;
public function __construct()
{
$this->orders = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId(): int
{
return $this->id;
}
public function setId(int $id): Product
{
$this->id = $id;
return $this;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): Product
{
$this->name = $name;
return $this;
}
public function getValue(): float
{
return $this->value;
}
public function setValue(float $value): Product
{
$this->value = $value;
return $this;
}
public function getOrders()
{
return $this->orders;
}
public function addOrder(Order $order)
{
if ($this->getOrders()->contains($order)) {
return $this;
}
$this->getOrders()->add($order);
$order->addProduct($this);
return $this;
}
public function removeOrder(Order $order)
{
if (!$this->getOrders()->contains($order)) {
return $this;
}
$this->getOrders()->removeElement($order);
$order->removeProduct($this);
return $this;
}
}
/**
* @Entity(repositoryClass="Repositories\OrderRepository")
* @Table(name="Orders")
*/
class Order
{
/**
* @Id
* @Column(type="integer")
* @GeneratedValue
*/
protected $id;
/**
* @Column(type="decimal", precision=10, scale=2)
*/
protected $totalValue;
/**
* @OneToMany(targetEntity="ProductOrder", mappedBy="order")
*/
protected $products;
public function __construct()
{
$this->products = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId(): int
{
return $this->id;
}
public function setId(int $id): Order
{
$this->id = $id;
return $this;
}
public function getTotalValue(): float
{
return $this->totalValue;
}
public function setTotalValue(float $totalValue): Order
{
$this->totalValue = $totalValue;
return $this;
}
public function getProducts()
{
return $this->products;
}
public function addProduct(Product $product)
{
if ($this->getProducts()->contains($product)) {
return $this;
}
$this->getProducts()->add($product);
$product->addOrder($this);
return $this;
}
public function removeProduct(Product $product)
{
if (!$this->getProducts()->contains($product)) {
return $this;
}
$this->getProducts()->removeElement($product);
$product->removeOrder($this);
return $this;
}
}
/**
* @Entity(repositoryClass="Repositories\ProductOrderRepository")
* @Table(name="ProductsOrders")
*/
class ProductOrder
{
/**
* @Id
* @ManyToOne(targetEntity="Order", inversedBy="products")
* @JoinColumn(name="order", referencedColumnName="id")
*/
protected $order;
/**
* @Id
* @ManyToOne(targetEntity="Product", inversedBy="orders")
* @JoinColumn(name="product", referencedColumnName="id")
*/
protected $product;
/**
* @Column(type="integer")
*/
protected $quantity;
/**
* @Column(type="decimal", precision=10, scale=2)
*/
protected $unityValue;
public function getOrder()
{
return $this->order;
}
public function setOrder($order)
{
$this->order = $order;
return $this;
}
public function getProduct()
{
return $this->product;
}
public function setProduct($product)
{
$this->product = $product;
return $this;
}
public function getQuantity()
{
return $this->quantity;
}
public function setQuantity($quantity)
{
$this->quantity = $quantity;
return $this;
}
public function getUnityValue()
{
return $this->unityValue;
}
public function setUnityValue($unityValue)
{
$this->unityValue = $unityValue;
return $this;
}
}
Example of using EM
<?php
$product = $em->getReference(User::class, 1);
$order = $em->getReference(User::class, 1);
$productOrder = new ProductOrder();
$productOrder
->setOrder($order)
->setProduct($product)
->setQuantity(5)
->setUnityValue(99.9);
// Isso está cadastrando corretamente.
$em->getRepository(ProductOrder::class)->create($productOrder);
// Porém, isso não está funcionando:
echo $order->getProducts()[0]->getQuantity();