[Dbix-class] many_to_many and polymorphism
Jess Robinson
castaway at desert-island.demon.co.uk
Wed Jan 10 08:38:43 GMT 2007
On Tue, 9 Jan 2007, Jason Gottshall wrote:
> I'm trying to figure out how to set up a polymorphic relationship using
> many_to_many, and I'm having a bit of trouble. Assume 4 tables:
>
> Actors: id, name
> ActorRoles: actor_id, charactername, production_id, production_type
> Films: id, title
> TVShows: id, title
>
> where ActorRoles.production_type is one of "film" or "tv" and
> ActorRoles.production_id is the foreign key in either the Films or
> TVShows table. So I've got this:
>
> package My::DBIC::Schema::Actor;
>
> __PACKAGE__->has_many( actor_roles =>
> 'My::DBIC::Schema::ActorRole',
> { 'foreign.actor_id' => 'self.id' } );
> __PACKAGE__->many_to_many( films =>
> 'actor_roles',
> 'film' );
> __PACKAGE__->many_to_many( tvshows =>
> 'actor_roles',
> 'tvshow' );
>
> package My::DBIC::Schema::ActorRole;
> __PACKAGE__->belongs_to( actor =>
> 'My::DBIC::Schema::Actor',
> { 'foreign.id' => 'self.actor_id' );
> __PACKAGE__->belongs_to( film =>
> 'My::DBIC::Schema::Film',
> { 'foreign.id' => 'self.production_id' } );
> __PACKAGE__->belongs_to( tvshow =>
> 'My::DBIC::Schema::TVShow',
> { 'foreign.id' => 'self.production_id' } );
>
> package My::DBIC::Schema::Film;
>
> __PACKAGE__->has_many( actor_roles =>
> 'My::DBIC::Schema::ActorRole',
> { 'foreign.production_id' => 'self.id' } );
> __PACKAGE__->many_to_many( actors =>
> 'actor_roles',
> 'actor' );
>
> package My::DBIC::Schema::TVShow;
>
> __PACKAGE__->has_many( actor_roles =>
> 'My::DBIC::Schema::ActorRole',
> { 'foreign.production_id' => 'self.id' } );
> __PACKAGE__->many_to_many( actors =>
> 'actor_roles',
> 'actor' );
>
> The problem is that I haven't accounted for the production_type in the
> relationships between Films/TVShows and ActorRoles. As long as the union
> of all film and tvshow ids is unique, my results are accurate. But that
> makes me nervous. I've searched the DBIC docs and and list archives and
> haven't yet come across anything that helps. Ideas?
>
In theory, it would be sane to do:
__PACKAGE__->belongs_to( film =>
'My::DBIC::Schema::Film',
{ 'foreign.id' => 'self.production_id',
'film' => 'self.production_type' } );
.. but in practice DBIC doesnt support that sort of join yet..
I'd solve it by creating a table of productiontypes, and then adding:
__PACKAGE__->belongs_to( production_type =>
'My::DBIC::Schema::ProductionTypes',
{ 'foreign.id' => 'self.production_type' } );
__PACKAGE__->belongs_to( film =>
'My::DBIC::Schema::Film',
{ 'foreign.id' => 'self.production_id' },
{ join => 'My::DBIC::Schema::ProductionTypes' } );
.. which will always add a one-to-one join to productiontypes when you
search via film, and thus restrict to the type in the production_type
field.
.. (I hope, untested ;)
Jess
More information about the Dbix-class
mailing list