saintmike has asked for the wisdom of the Perl Monks concerning the following question:

I just love Class::DBI. But I found something on the manpage that doesn't look right.

The manpage shows a cd table, linking to an artist table. For this, the cd table's artist field contains a numerical id which references the artist table's artistid field.

Now, Class::DBI hides this pretty well, once the has_a() relationship gets defined. If you get a CD object $cd as a result of a query, you can simply use $cd->artist()->name() to get to the artist table and to the name field from there.

However, further down, there's a code snippet that I don't think will work:

my $cd = Music::CD->find_or_create( { artist => "U2", title => "Boy" });
This seems to imply that you could use the artist field somewhat transparently and Class::DBI would figure out magically that you meant the artist table's name field.

Further below, there's another example:

my @music = Music::CD->search_where( artist => [ ’Ozzy’, ’Kelly’ ], status => { ’!=’, ’outdated’ }, );
This seems to imply that you could use Class::DBI::AbstractSearch to search Music::CD (mind you, not Music::Artist) for the artist field, which Class::DBI would then somehow magically map to the name field in the artist table. How would it know that? The mapping is between the cd table's artist field and the artist table's artistid field. Noone mentioned the name field.

Further down there's a search_like:

@cds = Music::CD->search_like( title => ’Hits%’, artist => ’Various%’);
Same thing. How would Music::CD know to match the content of the artist parameter against the name field of the artist table?

Finally, here's a code snippet to reproduce the behaviour. It doesn't find the artist because Class::DBI is looking for the artist ID, not, as advertised, for the artist name. SQL setup included. Any insight appreciated ...

package Music::DBI; use base qw(Class::DBI); Music::DBI->set_db("Main", "dbi:mysql:testdb", "root", ""); package Music::Artist; use base qw(Music::DBI); Music::Artist->table("artist"); Music::Artist->columns(All => qw/artistid name/); Music::Artist->has_many(cds => "Music::CD"); package Music::CD; use base qw(Music::DBI); use Class::DBI::AbstractSearch; Music::CD->table("cd"); Music::CD->columns(All => qw/cdid artist title year/); Music::CD->has_a(artist => "Music::Artist"); my $artist = Music::Artist->create({artistid => 1, name => "U2"}); my $cd = $artist->add_to_cds({ cdid => 1, title => "October", year => 1980, }); my @cds = Music::CD->search_like(artist => "%U%"); print $_->title(), "\n" for @cds; __END__ CREATE DATABASE IF NOT EXISTS testdb; USE testdb; CREATE TABLE IF NOT EXISTS cd ( cdid INTEGER PRIMARY KEY, artist INTEGER, # references ’artist’ title VARCHAR(255), year CHAR(4) ); CREATE TABLE IF NOT EXISTS artist ( artistid INTEGER PRIMARY KEY, name VARCHAR(255) );

Replies are listed 'Best First'.
Re: Class::DBI Manpage Swindle??
by dragonchild (Archbishop) on Mar 01, 2005 at 13:42 UTC
    Instead of calling it a swindle, call it a documentation bug and report it to the author. The best way to do that is to read the documentation and find out where the author wants bugs reported. If there isn't a place, use http://rt.cpan.org.

    Remember, CPAN modules go through numerous iterations, often several releases in a week. Features change and grow, and sometimes documentation gets left behind. Unlike code, for which you can write tests, it's a lot harder to keep documentation in sync with requirements. We often depend on our users to help us find documentation errors. Remember - we know how it works, so we miss places where it's confusing or just plain wrong.

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re: Class::DBI Manpage Swindle??
by itub (Priest) on Mar 01, 2005 at 12:24 UTC
    It is possible that the author was imagining an entirely different table (where artist is a varchar) when writing those examples. Those kinds of things sometimes by happen by accident when I write docs, and then the users rightfully complain about the confusion. If that's the case here, you should contact the maintainer of the distribution.
Re: Class::DBI Manpage Swindle??
by cbrandtbuffalo (Deacon) on Mar 01, 2005 at 14:54 UTC
    Class::DBI also has a site with a wiki here, Class::DBI.

    There is also a very active list and patches, even to the docs, are welcome: Class DBI list. You may want to check the list to see if a doc patch has been submitted. Sometimes someone has fixed something but the fix hasn't been released yet.

Re: Class::DBI Manpage Swindle??
by perrin (Chancellor) on Mar 01, 2005 at 16:36 UTC
    You are assuming that all of the examples in the docs refer to the same cd table definition. I don't see anything in there that says they do, and I assumed they didn't, for the same reasons you list here. If you find that confusing, I'd suggest sending in a doc patch that changes them to all refer to the same table definition or to explicitly state that they don't.
      Typically when I write a module, my docs are based directly off the results of the test suite: if I promise it in docs, I deliver it in tests.

      Does the CDBI test suite use the same schema throughout? Is there some way to import code directly from the test suite into the docs for coherence?

      And yes, I am in favor of one coherent schema for all the docs. And also in favor of that schema being deploying, perhaps like my DBSchema::Sample. Both Tony and Tim were interested in the project, but it sorta died (probably due to my own lack of initiative).