LMSouq
general-dev Open

Doctrine2: Best way to handle many-to-many with extra columns in reference table

CR
Crozin
1 month ago
3 views
Problem Description
I'm wondering what's the best, the cleanest and the most simply way to work with many-to-many relations in Doctrine2. Let's assume that we've got an album like [*Master of Puppets* by Metallica](http://www.last.fm/music/Metallica/Master+of+Puppets) with several tracks. But please note the fact that one track might appears in more that one album, like [*Battery* by Metallica](http://www.last.fm/music/Metallica/Master+of+Puppets/Battery) does - three albums are featuring this track. So what I need is many-to-many relationship between albums and tracks, using third table with some additional columns (like position of the track in specified album). Actually I have to use, as Doctrine's documentation suggests, a double one-to-many relation to achieve that functionality. /** @Entity() */ class Album { /** @Id @Column(type="integer") */ protected $id; /** @Column() */ protected $title; /** @OneToMany(targetEntity="AlbumTrackReference", mappedBy="album") */ protected $tracklist; public function __construct() { $this->tracklist = new \Doctrine\Common\Collections\ArrayCollection(); } public function getTitle() { return $this->title; } public function getTracklist() { return $this->tracklist->toArray(); } } /** @Entity() */ class Track { /** @Id @Column(type="integer") */ protected $id; /** @Column() */ protected $title; /** @Column(type="time") */ protected $duration; /** @OneToMany(targetEntity="AlbumTrackReference", mappedBy="track") */ protected $albumsFeaturingThisTrack; // btw: any idea how to name this relation? :) public function getTitle() { return $this->title; } public function getDuration() { return $this->duration; } } /** @Entity() */ class AlbumTrackReference { /** @Id @Column(type="integer") */ protected $id; /** @ManyToOne(targetEntity="Album", inversedBy="tracklist") */ protected $album; /** @ManyToOne(targetEntity="Track", inversedBy="albumsFeaturingThisTrack") */ protected $track; /** @Column(type="integer") */ protected $position; /** @Column(type="boolean") */ protected $isPromoted; public function getPosition() { return $this->position; } public function isPromoted() { return $this->isPromoted; } public function getAlbum() { return $this->album; } public function getTrack() { return $this->track; } } Sample data: Album +---...

AI-Generated Solution

Powered by LMSouq AI · GPT-4.1-mini

✓ Solution Ready
Analyzing problem and generating solution…
Was this solution helpful?
Back to Knowledge Base