[Maypole] the subtleties of many-to-many stringification

From: Seth Gordon (sethg at ropine.com)
Date: Thu Dec 02 2004 - 20:20:12 GMT


Work on my Maypolized library database is continuing apace, but I'm
confused by a certain detail.

My database has a "titles" table, an "authors" table, and a
"title_author_rel" table linking the two:

CREATE TABLE title_author_rel (
     title_id integer,
     author_id integer,
     relationship character(6) DEFAULT 'by'::bpchar
         -- 'by', 'ed.', 'trans.', etc.
);

I set up the relationship in my application package...

package JeevesLibrary;
#...
JeevesLibrary::TitleAuthorRel->has_a(title_id => 'JeevesLibrary::Titles');
JeevesLibrary::TitleAuthorRel->has_a(author_id => 'JeevesLibrary::Authors');

JeevesLibrary::Titles->has_many(authors =>
     [ JeevesLibrary::TitleAuthorRel => author_id ]);
JeevesLibrary::Authors->has_many(titles =>
     [ JeevesLibrary::TitleAuthorRel => title_id ]);

...and everything Just Worked, except for one small detail: the
"authors" list on the ...library/titles/view/#### page just has the
authors' names, and not the relationships.

I can make the list show relationships by changing the many-to-many
relationship and defining how to stringify title_author_rel:

package JeevesLibrary;
#...
JeevesLibrary::Titles->has_many(authors => 'JeevesLibrary::TitleAuthorRel');
# ...
# ...
package JeevesLibrary::TitleAuthorRel;
#...
sub stringify_self {
     my $self = shift;
     return $self->relationship . ' ' . $self->author_id;
}

This makes the names in the authors list show up a "by Smith" instead of
just "Smith", but then the links take me to a title_author_rel/view/###
page instead of an author_view/### page.

I tried adding a view method to JeevesLibrary::TitleAuthorRel that would
  look up the appropriate author object and swap it in (an object
switcheroo rather than the template switcheroo), but
When I try to add a "sub view :Exported {}" method to one of my model
packages, my module gets a compilation error:

Couldn't require JeevesLibrary - Invalid CODE attribute: Exported at
/home/sethg/bin/JeevesLibrary.pm line 106

Well, *that*'s damn strange.

I worked around this by overriding the process method in
JeevesLibrary::TitleAuthorRel:

sub process {
     my ($class, $r) = @_;
     my $method = $r->action;
     return if $r->{template};
     $r->{template} = $method;
     $r->objects( [] );
     my $tar = $class->retrieve($r->{args}->[0]);
     if ($tar) {
         my $author = $tar->author_id;
         $r->objects( [$author] ) if $author;
     }
     $r->model_class('JeevesLibrary::Authors');
     $r->{template_args}{title} =
         ' author / ' . $r->config->application_name;
     JeevesLibrary::Authors->$method($r, $author, @{ $r->{args} } );
}

This seems to work, but I am still wondering

(a) why I can't add :Exported methods, dammit
(b) if there is a more elegant way to do the same thing

-- 
// seth gordon // sethg at ropine.com // http://dynamic.ropine.com/yo/ //

_______________________________________________ maypole mailing list maypole at lists.netthink.co.uk http://lists.netthink.co.uk/listinfo/maypole



This archive was generated by hypermail 2.1.3 : Thu Feb 24 2005 - 22:25:57 GMT