I am trying to set up a system where I can use use 
Rose::DB::Object::Loader to auto make my modules any time I make a 
schema change.  Then I can have manually created classes that use the 
auto-generated classes as their base.  But, I am running into a problem 
with the relationships.

Here is a simple case.  I have a MySQL database with 3 tables: foos, 
bars, & foo_bar_map:

=========================================================
CREATE TABLE `foos` (
   `id` int(10) unsigned NOT NULL auto_increment,
   `name` varchar(50) NOT NULL default '',
   PRIMARY KEY  (`id`),
   UNIQUE KEY `name_phone_idx` (`name`)
);

CREATE TABLE `bars` (
   `id` int(10) unsigned NOT NULL auto_increment,
   `description` varchar(50) NOT NULL default '',
   PRIMARY KEY  (`id`)
);

CREATE TABLE `foo_bar_map` (
   `foo_id` int(10) unsigned NOT NULL default '0',
   `bar_id` int(10) unsigned NOT NULL default '0',
   PRIMARY KEY  (`foo_id`,`bar_id`),
   KEY `foo_id` (`foo_id`),
   KEY `bar_id` (`bar_id`),
   CONSTRAINT `foo_bar_map_ibfk_1` FOREIGN KEY (`foo_id`) REFERENCES 
`foos` (`id`),
   CONSTRAINT `foo_bar_map_ibfk_2` FOREIGN KEY (`bar_id`) REFERENCES 
`bars` (`id`)
)
=========================================================

The idea is to auto-create modules in the 'My::DB' namespace, i.e. 
My::DB::Foo. Then I create My::Foo which uses My::DB::Foo as it's base 
and allows me to put in all the other methods that I need to create 
manually to operate on foos.  When I change the schema, I can just 
re-generate everything in My::DB, and my other stuff is preserved.

So, I created a script that will generate everything in My::DB.  This 
script also goes through each generated module and swaps out the classes 
  for the relationships to point to my 'main' class. i.e. My::Foo 
instead of My::DB::Foo.  This is to ensure that I get the right class 
when I traverse the relationships.

When I run that script, I end up with these 3 modules:

=========================================================
package My::DB::Foo;

use strict;

use base qw(My::DB::DB::Object::AutoBase1);

__PACKAGE__->meta->setup(
     table   => 'foos',

     columns => [
         id   => { type => 'integer', not_null => 1 },
         name => { type => 'varchar', default => '', length => 50, 
not_null => 1 },
     ],

     primary_key_columns => [ 'id' ],

     unique_key => [ 'name' ],

     relationships => [
         bars => {
             column_map    => { foo_id => 'id' },
             foreign_class => 'My::Bar',
             map_class     => 'My::FooBarMap',
             map_from      => 'foo',
             map_to        => 'bar',
             type          => 'many to many',
         },
     ],
);

package My::DB::Bar;

use strict;

use base qw(My::DB::DB::Object::AutoBase1);

__PACKAGE__->meta->setup(
     table   => 'bars',

     columns => [
         id          => { type => 'integer', not_null => 1 },
         description => { type => 'varchar', default => '', length => 
50, not_null => 1 },
     ],

     primary_key_columns => [ 'id' ],

     relationships => [
         foos => {
             column_map    => { bar_id => 'id' },
             foreign_class => 'My::Foo',
             map_class     => 'My::FooBarMap',
             map_from      => 'bar',
             map_to        => 'foo',
             type          => 'many to many',
         },
     ],
);

package My::DB::FooBarMap;

use strict;

use base qw(My::DB::DB::Object::AutoBase1);

__PACKAGE__->meta->setup(
     table   => 'foo_bar_map',

     columns => [
         foo_id => { type => 'integer', not_null => 1 },
         bar_id => { type => 'integer', not_null => 1 },
     ],

     primary_key_columns => [ 'foo_id', 'bar_id' ],

     foreign_keys => [
         bar => {
             class       => 'My::Bar',
             key_columns => { bar_id => 'id' },
         },

         foo => {
             class       => 'My::Foo',
             key_columns => { foo_id => 'id' },
         },
     ],
);
=============================================


My::Foo would look something like this:

====
package My::Foo;

use strict;
use base qw(My::Foo);

# class and instance methods here.......

1;
====


Here's where the problem comes in.  I have this test script:

====
#!/usr/bin/perl
use My::Foo;
use Data::Dumper;

my $f = My::Foo->new(id => 1);
$f->load;

foreach my $bar (@{$f->bars}) {
   print Dumper($bar);
}
====


When I run it I get this error:

Can't locate object method "bars" via package "My::Foo" at 
/usr/lib/perl5/site_perl/5.8.5/Rose/DB/Object.pm line 1464
         Rose::DB::Object::AUTOLOAD('My::Foo=HASH(0x88a6ee0)') called at 
test.pl line 7

If I don't change the classes for the relationships in my auto-generate 
script, then it works fine.  But, then my $bar objects are of the class 
My::DB::Bar and I need them to be My::Bar.

I would assume there are other people trying to do something similar to 
this.  Am I missing something?  or do I just need to suck it up and 
manage the meta data manually?

-Bryan




-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object

Reply via email to