[Dbix-class] Many-to-many with attributes

Jonathan Tweed jonathan at tweed.name
Sat Nov 26 13:06:19 CET 2005


Hi List

I'm trying to create a many-to-many mapping with attributes on the  
join table. I've got the many-to-many bit working, but can't figure  
out how to get at the attributes. My current attempt is as follows:

package DB::List;

use strict;
use warnings;
use base 'DB';

__PACKAGE__->table('list');
__PACKAGE__->add_columns(qw/id client name internal/);
__PACKAGE__->set_primary_key('id');
__PACKAGE__->belongs_to('client' => 'DB::Client');
__PACKAGE__->has_many('list_subscribers' => 'DB::ListSubscriber');

sub subscribers {
     my ($self) = @_;

     return DB::Subscriber->search(
         { 'list.id' => $self->id },
         {
             join => { 'list_subscribers' => 'list' },
             cols => ['me.id', 'me.email',  
'list_subscribers.subscribed', 'list_subscribers.unsubscribed'],
             order_by => 'email'
         });
}

1;

package DB::ListSubscriber;

use strict;
use warnings;
use base 'DB';

__PACKAGE__->table('list_subscriber');
__PACKAGE__->add_columns(qw/list subscriber subscribed unsubscribed/);
__PACKAGE__->set_primary_key(qw/list subscriber/);
__PACKAGE__->belongs_to('list' => 'DB::List');
__PACKAGE__->belongs_to('subscriber' => 'DB::Subscriber');

1;

package DB::Subscriber;

use strict;
use warnings;
use base 'DB';

__PACKAGE__->table('subscriber');
__PACKAGE__->add_columns(qw/id email/);
__PACKAGE__->set_primary_key('id');
__PACKAGE__->has_many('list_subscribers' => 'DB::ListSubscriber');

sub list {
     my ($self) = @_;

     return DB::List->search(
         { 'subscriber.id' => $self->id },
         { join => { 'list_subscribers' => 'subscriber' } });
}

1;

When I do $list->subscribers, the following SQL statement is produced:

SELECT me.id, me.email, list_subscribers.subscribed,  
list_subscribers.unsubscribed FROM subscriber me LEFT JOIN  
list_subscriber list_subscribers ON ( list_subscribers.subscriber =  
me.id )  JOIN list list ON ( list.id = list_subscribers.list ) WHERE  
( list.id = ? ) ORDER BY email

which when I run it againt the database returns exactly what I want.  
However a $list->subscribers->next produces

'subscriber' => bless( {
                                    '_in_storage' => 1,
                                    '_column_data' => {
                                                        'email' =>  
'jonathan at tweed.name',
                                                        'id' => '2'
                                                      }
                                  },  
'FreshInfusion::Model::DB::Subscriber' )

which does not contain the extra columns. Where am I going wrong?

Thanks for any help, I'm an ex Class::DBI user but very new to  
DBIx::Class and so far I'm impressed. When I get this working I'll  
add an example to the wiki.

Jon



More information about the Dbix-class mailing list