Doctrine 2 and Many-to-many link table with an extra field
A Many-To-Many association with additional values is not a Many-To-Many, but is indeed a new entity, since it now has an identifier (the two relations to the connected entities) and values.
That's also the reason why Many-To-Many associations are so rare: you tend to store additional properties in them, such as sorting
, amount
, etc.
What you probably need is something like following (I made both relations bidirectional, consider making at least one of them uni-directional):
Product:
namespace Entity;use Doctrine\ORM\Mapping as ORM;/** @ORM\Table(name="product") @ORM\Entity() */class Product{ /** @ORM\Id() @ORM\Column(type="integer") */ protected $id; /** ORM\Column(name="product_name", type="string", length=50, nullable=false) */ protected $name; /** @ORM\OneToMany(targetEntity="Entity\Stock", mappedBy="product") */ protected $stockProducts;}
Store:
namespace Entity;use Doctrine\ORM\Mapping as ORM;/** @ORM\Table(name="store") @ORM\Entity() */class Store{ /** @ORM\Id() @ORM\Column(type="integer") */ protected $id; /** ORM\Column(name="store_name", type="string", length=50, nullable=false) */ protected $name; /** @ORM\OneToMany(targetEntity="Entity\Stock", mappedBy="store") */ protected $stockProducts;}
Stock:
namespace Entity;use Doctrine\ORM\Mapping as ORM;/** @ORM\Table(name="stock") @ORM\Entity() */class Stock{ /** ORM\Column(type="integer") */ protected $amount; /** * @ORM\Id() * @ORM\ManyToOne(targetEntity="Entity\Store", inversedBy="stockProducts") * @ORM\JoinColumn(name="store_id", referencedColumnName="id", nullable=false) */ protected $store; /** * @ORM\Id() * @ORM\ManyToOne(targetEntity="Entity\Product", inversedBy="stockProducts") * @ORM\JoinColumn(name="product_id", referencedColumnName="id", nullable=false) */ protected $product;}
Doctrine handles many-to-many relationships just fine.
The problem that you're having is that you don't need a simple ManyToMany association, because associations can't have "extra" data.
Your middle (stock) table, since it contains more than product_id and store_id, needs its own entity to model that extra data.
So you really want three classes of entity:
- Product
- StockLevel
- Store
and two associations:
- Product oneToMany StockLevel
- Store oneToMany StockLevel