the old way of doing this was to set up an AuthorBook class that had_a book and had_a author, and then use the nearly ubiquitous idiom:
Package Author;
Author->has_many('_book_links', 'AuthorBook', 'author');
sub books { return map { $_->book } shift->_book_links; }
but as of 0.91ish, you can achieve exactly the same thing with:
Package Author;
Author->has_many('books', [ AuthorBook => 'book' ], 'author');
The syntax is getting rather arbitrary (I'd really like to see named parameters there), and you still have to create the nearly-empty AuthorBook class, but that's kind of a good thing - there will probably be methods you want to add to it one day - and at least this way the relationships are defined where it makes most sense to look for them.
ps. the author of Class::DBI::Join was Michael Schwern, also the original author of Class::DBI and the main reason why it's so simple, powerful, horrible inside and reliant on strange non-standard pragmas that Make OOP More Fun (to Schwern). All will kneel.