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

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


I've opened a similar question in the Doctrine user mailing list and got a really simple answer;

consider the many to many relation as an entity itself, and then you realize you have 3 objects, linked between them with a one-to-many and many-to-one relation.

http://groups.google.com/group/doctrine-user/browse_thread/thread/d1d87c96052e76f7/436b896e83c10868#436b896e83c10868

Once a relation has data, it's no more a relation !


From $album->getTrackList() you will alwas get "AlbumTrackReference" entities back, so what about adding methods from the Track and proxy?

class AlbumTrackReference{    public function getTitle()    {        return $this->getTrack()->getTitle();    }    public function getDuration()    {        return $this->getTrack()->getDuration();    }}

This way your loop simplifies considerably, aswell as all other code related to looping the tracks of an album, since all methods are just proxied inside AlbumTrakcReference:

foreach ($album->getTracklist() as $track) {    echo sprintf("\t#%d - %-20s (%s) %s\n",         $track->getPosition(),        $track->getTitle(),        $track->getDuration()->format('H:i:s'),        $track->isPromoted() ? ' - PROMOTED!' : ''    );}

Btw You should rename the AlbumTrackReference (for example "AlbumTrack"). It is clearly not only a reference, but contains additional logic. Since there are probably also Tracks that are not connected to an album but just available through a promo-cd or something this allows for a cleaner separation also.


Nothing beats a nice example

For people looking for a clean coding example of an one-to-many/many-to-one associations between the 3 participating classes to store extra attributes in the relation check this site out:

nice example of one-to-many/many-to-one associations between the 3 participating classes

Think about your primary keys

Also think about your primary key. You can often use composite keys for relationships like this. Doctrine natively supports this. You can make your referenced entities into ids.Check the documentation on composite keys here