The idea is as follows: there are products simple and compound. Compound products may consist of few simple products, for example:
There is product "Cocktail" - a simple product, with its own characteristics (name, description, price etc.), and there is a compound product - the "Fountain of cocktails," which includes the product "Cocktail" as a main component. One "Fountain of cocktails" consists of 50 "Cocktail".
Right now I have the Product entity which has many-to-many relationship with self-referencing:
<?php
namespace CT\AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Class Product
*
* @ORM\Entity
* @ORM\Table(name="products")
*/
class Product
{
/**
* @ORM\id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*
* @var int
*/
protected $id;
/**
* @ORM\Column(type="string")
*
* @var string
*/
protected $name;
/**
* @ORM\Column(
* name="description",
* type="text"
* )
*
* @var string
*/
protected $desc;
/**
* @ORM\Column(type="float")
*
* @var float
*/
protected $price;
/**
* @ORM\Column(
* name="count_type",
* type="string"
* )
*
* @var string
*/
protected $countType;
/**
* @ORM\Column(
* name="default_count",
* type="integer",
* options={"unsigned": true}
* )
*
* @var int
*/
protected $defCount;
/**
* @ORM\Column(type="boolean")
*
* @var bool
*/
protected $isCountable;
/**
* @ORM\Column(type="boolean")
*
* @var bool
*/
protected $isCompound;
/**
* @ORM\ManyToMany(
* targetEntity="Product",
* mappedBy="components"
* )
*
* @var ArrayCollection
*/
private $products;
/**
* @ORM\ManyToMany(
* targetEntity="Product",
* inversedBy="products"
* )
* @ORM\JoinTable(
* name="compound_products",
* joinColumns={
* @ORM\JoinColumn(
* name="main_product_id",
* referencedColumnName="id"
* )
* },
* inverseJoinColumns={
* @ORM\JoinColumn(
* name="component_product_id",
* referencedColumnName="id"
* )
* }
* )
*
* @var ArrayCollection
*/
private $components;
/**
* Product constructor.
*/
public function __construct()
{
$this->products = new ArrayCollection();
$this->components = new ArrayCollection();
}
// Getters & setters...
}
I want to add extra field amount to compound_products table for setting the amount of simple products in one compound product, to get an output: http://prntscr.com/cgdvc3
I found one solution, but I don't quite understand how to apply it to my problem: Doctrine many to many self referencing with extra columns
Could you explain me how could I add this extra field for my task with saving the relationship many-to-many with self-referencing? Or if you has better solution could you share it?
You need to create a separate entity to link your Entities. Something like ProductCompound.
And then link it twice to your Product entity, for each relation.
/**
* Class ProductCompound
*
* @ORM\Entity
* @ORM\Table(name="compound_products")
*/
class ProductCompound
{
/**
* @ORM\id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*
* @var int
*/
protected $id;
/**
* @ORM\ManyToOne(
* targetEntity="Product",
* inversedBy="products"
* )
* @ORM\JoinColumn(name="main_product_id", referencedColumnName="id"
*
* @var ArrayCollection
*/
protected $mainProduct;
/**
* @ORM\ManyToOne(
* targetEntity="Product",
* inversedBy="components"
* )
* @ORM\JoinColumn(name="component_product_id", referencedColumnName="id"
*
* @var ArrayCollection
*/
protected $componentProduct;
/**
* @var double
*
* @ORM\Column(name="amount", type="float", nullable=true)
*/
protected $amount;
And modify Product:
/**
* Class Product
*
* @ORM\Entity
* @ORM\Table(name="products")
*/
class Product
{
...
/**
* @ORM\OneToMany(
* targetEntity="ProductCompound",
* mappedBy="mainProduct"
* )
*
* @var ArrayCollection
*/
private $productLinks;
/**
* @ORM\OneToMany(
* targetEntity="ProductCompound",
* mappedBy="componentProduct"
* )
*
* @var ArrayCollection
*/
private $componentLinks;