From: Matt S Trout Date: Fri, 14 Aug 2009 11:12:41 +0000 (+0100) Subject: rel copying. weird recursive dependency problem though. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=490d5481d31e1ec638e07e21b8bbbdc3b161297d;p=dbsrgits%2FDBIx-Class-ResultSource-MultipleTableInheritance.git rel copying. weird recursive dependency problem though. --- diff --git a/lib/DBIx/Class/ResultSource/MultipleTableInheritance.pm b/lib/DBIx/Class/ResultSource/MultipleTableInheritance.pm index f775530..2606b95 100644 --- a/lib/DBIx/Class/ResultSource/MultipleTableInheritance.pm +++ b/lib/DBIx/Class/ResultSource/MultipleTableInheritance.pm @@ -98,6 +98,52 @@ method _attach_additional_sources () { $self->columns ); $table->set_primary_key($self->primary_columns); + + # we need to copy our rels to the raw object as well + # note that ->add_relationship on a source object doesn't create an + # accessor so we can leave that part in the attributes + + # if the other side is a table then we need to copy any rels it has + # back to us, as well, so that they point at the raw table. if the + # other side is an MTI view then we need to create the rels to it to + # point at -its- raw table; we don't need to worry about backrels because + # it's going to run this method too (and its raw source might not exist + # yet so we can't, anyway) + + foreach my $rel ($self->relationships) { + my $rel_info = $self->relationship_info($rel); + + my $f_source = $schema->source($rel_info->{source}); + + # __PACKAGE__ is correct here because subclasses should be caught + + my $one_of_us = $f_source->isa(__PACKAGE__); + + my $f_source_name = $f_source->${\ + ($one_of_us ? 'raw_source_name' : 'source_name') + }; + + $table->add_relationship( + '_'.$rel, $f_source_name, @{$rel_info}{qw(cond attrs)} + ); + + unless ($one_of_us) { + my $reverse = do { + # we haven't been registered yet, so reverse_ cries + # XXX this is evil and will probably break eventually + local @{$schema->source_registrations} + {map $self->$_, qw(source_name result_class)} + = ($self, $self); + $self->reverse_relationship_info($rel); + }; + foreach my $rev_rel (keys %$reverse) { + $f_source->add_relationship( + '_raw_'.$rev_rel, $raw_name, @{$reverse->{$rev_rel}}{qw(cond attrs)} + ); + } + } + } + $schema->register_source($raw_name => $table); } diff --git a/t/01load.t b/t/01load.t index 4dfc3f1..e5bebd3 100644 --- a/t/01load.t +++ b/t/01load.t @@ -35,3 +35,5 @@ is( warn Dumper $raw_bar->_columns; warn Dumper $raw_bar->_relationships; + +warn Dumper(MTITest->source('JustATable')->_relationships); diff --git a/t/lib/MTITest/Result/Bar.pm b/t/lib/MTITest/Result/Bar.pm index 206b340..c47448f 100644 --- a/t/lib/MTITest/Result/Bar.pm +++ b/t/lib/MTITest/Result/Bar.pm @@ -10,4 +10,16 @@ __PACKAGE__->add_columns( b => { data_type => 'integer' } ); +__PACKAGE__->belongs_to( + 'b_thang', + 'MTITest::Result::JustATable', + { 'foreign.id' => 'self.b' }, +); + +__PACKAGE__->has_many( + 'foos', + 'MTITest::Result::Foo', + { 'foreign.a' => 'self.id' } +); + 1; diff --git a/t/lib/MTITest/Result/Foo.pm b/t/lib/MTITest/Result/Foo.pm index 7d5f82d..450271d 100644 --- a/t/lib/MTITest/Result/Foo.pm +++ b/t/lib/MTITest/Result/Foo.pm @@ -11,9 +11,15 @@ __PACKAGE__->table('foo'); __PACKAGE__->add_columns( id => { data_type => 'integer', is_auto_increment => 1 }, - a => { data_type => 'text' } + a => { data_type => 'integer' } ); __PACKAGE__->set_primary_key('id'); +__PACKAGE__->belongs_to( + 'bar', + 'MTITest::Result::Bar', + { 'foreign.id' => 'self.a' } +); + 1; diff --git a/t/lib/MTITest/Result/JustATable.pm b/t/lib/MTITest/Result/JustATable.pm new file mode 100644 index 0000000..08c602f --- /dev/null +++ b/t/lib/MTITest/Result/JustATable.pm @@ -0,0 +1,21 @@ +package MTITest::Result::JustATable; + +use base qw(DBIx::Class::Core); + +__PACKAGE__->table('just_a_table'); + +__PACKAGE__->add_columns( + id => { data_type => 'integer', is_auto_increment => 1 }, + name => { data_type => 'varchar', size => 255 } +); + +__PACKAGE__->set_primary_key('id'); + +__PACKAGE__->has_many( + 'bars', + 'MTITest::Result::Bar', + { 'foreign.b' => 'self.id' } +); + + +1;