On 1/9/06, Scott Karns <[EMAIL PROTECTED]> wrote:
> package School::CourseSection;
> ...
> __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 School::ClassInstructor;
> ...
> __PACKAGE__->meta->foreign_keys
> (
>   the_class  => { class       => 'School::CourseSection',
>                   key_columns => { clid => 'clid' } },
>
>   instructor => { class       => 'School::Person',
>                   key_columns => { pid  => 'pid' } }
> );
> ...
> my $class_iter =
>   School::CourseSection::Manager->get_classes_iterator
>     ( require_objects   => [ qw(instructors.instructor
>                                 course
>                                 room)
>                            ],
>       sort_by           => 'lname, fname',
>       multi_many_ok     => 1,
>       );

I think your mistake is in the require_objects list.

In School::CourseSection, you define a many-to-many relationship named
"instructors" that connects a School::CourseSection object with a list
of School::Person objects though the mapping table/class
School::ClassInstructor.  The relationships and foreign keys seem to
be set up correctly.

In usage, many-to-many relationships make the mapping table (mostly)
"invisible."  So if you had a School::CourseSection object:

    $cs = School::CourseSection->new(...)->load;

you could get its list of instructors through the many-to-many
relationship like this:

    $instructors = $cs->instructors;

Behind the scenes, the instructors() method would go through the map
table to find the instructors, but all it returns is a list of those
instructors (School::Person objects).  The mapping table records are
discarded.

This is part of the purpose of many-to-many relationships.  When
there's a table between two other tables whose only purpose is to
connect records from the two tables, it's convenient to be able to
pretend that table doesn't exist.

(If that's not what you want, then you could just make a one-to-many
to the map table from both "sides" of the relationship, and then go
through the table connections "the long way."  But it doesn't seem
like you want that :)

So, in your get_classes_iterator() call, if you want to get the
associated instructors for each School::CourseSection object, you just
ask for them the same way:

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

That should work.  If it doesn't, please post the CREATE TABLE
statements for all of the tables involved and I'll see if I can debug
it.  The solution above is just off the top of my head.

Also, I don't think you need the "multi_many_ok" parameter since I
only see one "... to many" relationship in the require_objects list:
"instructors."  The other two, "course" and "room", are foreign keys
which are always "... to one".  The multi_many_ok parameter won't hurt
anything, of course, but it's not strictly needed here.

Finally, you will need to qualify the sort_by values.  Unqualified
values are assumed to belong to the primary table ("course_section" in
this case).  You can qualify sort_by column names by prepending table
names, tN table aliases, or relationship names.  Relationship names
are probably the most clean.  I also recommend an arrayref rather than
a comma-separated string.  Some examples (also untested, sorry)

    # table names
    sort_by => [ 'person.lname', 'person.fname' ],

    # tN table aliases
    sort_by => [ 't3.lname', 't3.fname' ],

    # Relationship name
    sort_by => [ 'instructors.lname', 'instructors.fname' ],

So, the final call:

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

Let me know how close I came to producing working code in my examples :)

-John


-------------------------------------------------------
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_idv37&alloc_id865&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