Hello. I recently began trying out Rose::DB::Object
and have run into some problems with foreign
keys/relationships. I'm working with an existing
postgresql database, so the naming conventions are my
own, not RDBO's.

My current problem revolves around a many-to-many
relation that is defined as follows.

lib/School/CourseSection.pm:
===========================>
package School::CourseSection;
use strict;

use base 'School::DB::Object';
use School::Course;
use School::Room;
use School::ClassInstructor;
use School::ClassStudent;

__PACKAGE__->meta->table( 'course_section' );

__PACKAGE__->meta->columns
    ( clid      => { type       => 'serial',
                     not_null   => 1,
                   },
      cid       => { type       => 'int',
                     not_null   => 1,
                   },
      sect_num  => { type       => 'smallint',
                     not_null   => 1,
                   },
      rmid      => { type       => 'int',
                     not_null   => 1,
                   },
      );

__PACKAGE__->meta->primary_key_columns( 'clid' );

__PACKAGE__->meta->add_unique_keys( 'cid',
                                    'sect_num',
                                    );

__PACKAGE__->meta->foreign_keys
    ( course    => { class      => 'School::Course',
                     key_columns=> { cid  => 'cid' },
                   },
      room      => { class      => 'School::Room',
                     key_columns=> { rmid => 'rmid' },
                   }
      );

__PACKAGE__->meta->relationships
    ( instructors => { type     => 'many to many',
                       map_class=>
'School::ClassInstructor',
                       map_from => 'the_class',
                       map_to   => 'instructor',
                     },
      students    => { type     => 'many to many',
                       map_class=>
'School::ClassStudent',
                       map_from => 'the_class',
                       map_to   => 'student',
                    }
      );

__PACKAGE__->meta->initialize;

package School::CourseSection::Manager;
use strict;

use base 'Rose::DB::Object::Manager';

sub object_class { 'School::CourseSection' }

__PACKAGE__->make_manager_methods( 'classes' );

1;
<==========================
lib/School/ClassInstructor.pm:
=============================>
package School::ClassInstructor;
use strict;

use base 'School::DB::Object';
use School::CourseSection;
use School::Person;

__PACKAGE__->meta->table( 'class_instructor' );

__PACKAGE__->meta->columns
    ( clid      => { type       => 'int',
                     not_null   => 1,
                   },
      pid       => { type       => 'int',
                     not_null   => 1,
                   },
      );

__PACKAGE__->meta->primary_key_columns( 'clid',
                                        'pid'
                                        );

__PACKAGE__->meta->foreign_keys
    ( the_class  => { class      =>
'School::CourseSection',
                      key_columns=> { clid => 'clid'
},
                    },
      instructor => { class      => 'School::Person',
                      key_columns=> { pid  => 'pid' },
                    }
      );

__PACKAGE__->meta->initialize;

package School::ClassInstructor::Manager;
use strict;

use base 'Rose::DB::Object::Manager';

sub object_class { 'School::ClassInstructor' }

__PACKAGE__->make_manager_methods( 'class_instructors'
);

1;
<=============================
lib/School/ClassStudent.pm:
==========================>
package School::ClassStudent;

use strict;

use base 'School::DB::Object';
use School::CourseSection;
use School::Person;

__PACKAGE__->meta->table( 'class_student' );

__PACKAGE__->meta->columns
    ( clid      => { type       => 'int',
                     not_null   => 1,
                   },
      pid       => { type       => 'int',
                     not_null   => 1,
                   },
      );

__PACKAGE__->meta->primary_key_columns( 'clid',
                                        'pid',
                                        );

__PACKAGE__->meta->foreign_keys
    ( the_class => { class      =>
'School::CourseSection',
                     key_columns=> { clid => 'clid' },
                   },
      student   => { class      => 'School::Person',
                     key_columns=> { pid  => 'pid' },
                   },
      );

__PACKAGE__->meta->initialize;

package School::ClassStudent::Manager;
use strict;

use base 'Rose::DB::Object::Manager';

sub object_class { 'School::ClassStudent' }

__PACKAGE__->make_manager_methods( 'class_students' );

1;
<==========================
lib/School/Course.pm:
====================>
package School::Course;

use strict;

use base 'School::DB::Object';

__PACKAGE__->meta->table( 'course' );

__PACKAGE__->meta->columns
    ( cid       => { type       => 'serial',
                     not_null   => 1,
                   },
      cnum      => { type       => 'smallint',
                     not_null   => 1,
                   },
      short_cname=> { type      => 'varchar',
                      length    => 10,
                      not_null  => 1,
                   },
      long_cname=> { type       => 'varchar',
                     length     => 128,
                   },
      );

__PACKAGE__->meta->primary_key_columns( 'cid' );

__PACKAGE__->meta->initialize;

package School::Course::Manager;

use strict;

use base 'Rose::DB::Object::Manager';

sub object_class { 'School::Course' }

__PACKAGE__->make_manager_methods( 'courses' );

1;
<====================
lib/School/Room.pm:
==================>
package School::Room;
use strict;

use base 'School::DB::Object';

__PACKAGE__->meta->table( 'room' );

__PACKAGE__->meta->columns
    ( rmid      => { type       => 'serial',
                     not_null   => 1,
                   },
      short_rmname=> { type     => 'varchar',
                       length   => 8,
                       not_null => 1,
                     },
      long_rmname => { type     => 'varchar',
                       length   => 32,
                     },
      );

__PACKAGE__->meta->primary_key_columns( 'rmid' );

__PACKAGE__->meta->initialize;

package School::Room::Manager;
use strict;

use base 'Rose::DB::Object::Manager';

sub object_class { 'School::Room' }

__PACKAGE__->make_manager_methods( 'rooms' );

1;
<==================
lib/School/Person.pm:
====================>
package School::Person;
use strict;

use base 'School::DB::Object';

__PACKAGE__->meta->table( 'person' );

__PACKAGE__->meta->columns
    ( pid       => { type       => 'serial',
                     not_null   => 1,
                   },
      lname     => { type       => 'varchar',
                     length     => 32,
                     not_null   => 1,
                   },
      fname     => { type       => 'varchar',
                     length     => 32,
                     not_null   => 1,
                   },
      miname    => { type       => 'varchar',
                     length     => 32,
                   },
      sex       => { type       => 'char',
                     length     => 1,
                   },
      dob       => { type       => 'date',
                   },
#     picture   => { type       => 'oid',
#                  },
      );

__PACKAGE__->meta->primary_key_columns( 'pid' );

__PACKAGE__->meta->initialize;

package School::Person::Manager;
use strict;

use base 'Rose::DB::Object::Manager';

sub object_class { 'School::Person' }

__PACKAGE__->make_manager_methods( 'people' );

1;
<====================
test-rdbo.pl:
============>
#!/usr/bin/perl
use strict;

use lib "/home/scott/projects/da-db/lib";

use School::CourseSection;
use School::Course;
use School::Person;
use School::Room;
use School::ClassInstructor;

local $Rose::DB::Object::Debug = 1;
local $Rose::DB::Object::Manager::Debug = 1;

my $class_iter =
  School::CourseSection::Manager->get_classes_iterator
    ( require_objects   => [ qw(instructors.instructor
                                course
                                room)
                           ],
      sort_by           => 'lname, fname',
      multi_many_ok     => 1,
      );

while (my $class = $class_iter->next) {
    print $class->instructors->instructor->fname, " ",
          $class->instructors->instructor->lname, "
teaches ",
          $class->course->short_cname, ", section ",
          $class->sect_num,
          " in ", $class->room->short_rmname, ".\n";
    }
<============

The problem occurs when I run the simple test program
above. I get the error:
School::CourseSection - no foreign key or relationship
named 'instructor' at
/usr/lib/perl5/vendor_perl/5.8.7/Rose/DB/Object/Manager.pm
line 656
       
Rose::DB::Object::Manager::get_objects('School::CourseSection::Manager',
'require_objects', 'ARRAY(0x804bd14)', 'sort_by',
'lname, fname', 'multi_many_ok', 1, 'return_iterator',
1, ...) called at
/usr/lib/perl5/vendor_perl/5.8.7/Rose/DB/Object/Manager.pm
line 240
       
Rose::DB::Object::Manager::__ANON__('School::CourseSection::Manager',
'require_objects', 'ARRAY(0x804bd14)', 'sort_by',
'lname, fname', 'multi_many_ok', 1) called at
test-rdbo.pl line 15

So, my questions:

1) Have I correctly defined the many-to-many relation?
2) Am I making an error in the way I have chained the
relations
   in my query?

My CourseSection class was originally named Class, but
I suspected that was asking for trouble by way of
method name collisions, so I renamed it to
CourseSection. I've been able to get simple one-to-one
relations to behave as expected, but I'm stuck here.

Also, if it matters, Rose::DB is version 0.59 and
Rose::DB::Object is version 0.62.

Any help or insight anyone might offer would be much
appreciated.

Scott Karns


                
__________________________________________ 
Yahoo! DSL – Something to write home about. 
Just $16.99/mo. or less. 
dsl.yahoo.com 



-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
_______________________________________________
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object

Reply via email to