We have albums, and songs. An album can have many songs, and a song can be found on multiple albums. So far that sounds like a normal many-to-many relationship. What if we want to store some additional information about the relation of album and song, let's say the position of the song on the album, maybe some text or whatever which is just meant to be displayed on that album-song relation.
To transfrom this into code, specifically Symfony2 code we will need the following three classes:
- Album
- Song
- AlbumSong
Your\ExampleBundle\Entity\Album: type: entity table: album id: id: type: integer generator: { strategy: AUTO } fields: name: type: string length: 100 description: type: text nullable: true oneToMany: songs: targetEntity: AlbumSong mappedBy: song cascade: [persist]
Your\ExampleBundle\Entity\Song: type: entity table: song id: id: type: integer generator: { strategy: AUTO } fields: name: type: string length: 100 description: type: text nullable: true oneToMany: albums: targetEntity: AlbumSong mappedBy: album cascade: [persist]
Your\ExampleBundle\Entity\AlbumSong: type: entity table: album_song id: id: type: integer generator: { strategy: AUTO } fields: label: type: string length: 100 whatever: type: boolean manyToOne: album: targetEntity: Album cascade: [persist] inversedBy: songs joinColumn: name: album_id referencedColumnName: id song: targetEntity: Song cascade: [persist] inversedBy: albums joinColumn: name: song_id referencedColumnName: id
I have read the doctrine documentation about bidirectional relations, but I don't yet understand what role the key "inversedBy" plays, so if anybody could enlight, or point me to an example that would be awesome.
Based on this, you can now generate your classes via app/console doctrine:generate:entities YourExampleBundle. Then you can fill up your database with fixtures like that for example:
$album = new Album(); $album->setDescription("Description of Party Rocking"); $album->setName("SorryForPartyRocking"); $song = new Song(); $song->setName("Sexy and I Know It"); $song2 = new Song(); $song2->setName("Sorry for Party Rocking"); $album_song = new AlbumSong(); $album_song->setAlbum($album); $album_song->setSong($song); $album_song->setExtraInfo("Extra Info to Sexy and I Know it. Only available on the album SorryForPartyRocking"); $album_song2 = new AlbumSong(); $album_song2->setAlbum($album); $album_song2->setSong($song2); $album_song2->setExtraInfo("Extra Info to Sorry for Party Rocking. Only available on the album SorryForPartyRocking"); $manager->persist($album_song); $manager->persist($album_song2); $manager->flush();
That's the way I think is correct, but maybe there are better ways to do that. If you can point me to a well documented, better solution, I would be very happy about that.
Otherwise I hope that helps a bit.
Hi Reto Ryter
ReplyDeleteThis is a nice post that I have seen. You explained well the many to many relation with extra field.Did you know how to make a form for that mapping entity with one field is mutiple check box. I had created the form for that mapping class ,but I couldn't persist my form, because that check box field becomes an array collection.How to persist for this type of form?
Hello Ashish.A.P
ReplyDeleteI will look into that this weekend, and then let you know if I find out anything.
Regards
Hello Reto Ryter
DeleteThank you for your quick response.Did you tried this?
I'd also be interested to see if you've made any further progress with this.
ReplyDeleteRob Ganly
No progress.. =)
ReplyDeleteThis is great, thanks!!
ReplyDeletephp app/console doctrine:schema:validate
ReplyDelete[Mapping] FAIL - The entity-class 'Test\TestBundle\Entity\Song' mapping is invalid
* The mappings Test\TestBundle\Entity\Album#songs and Test\TestBundle\Entity\AlbumSong#song are incosistent with each other.
and two more errors :(
I too get the above error... spent hours trying to figure it out to no avail. Have a post on SO, but not had any feedback yet.
ReplyDeletehttp://stackoverflow.com/questions/22417318/the-mappings-entity-and-entity-are-inconsistent-with-each-other-symfony2-d
Thanks ! very helpful
ReplyDelete