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

I am trying to move some existing database to Class::DBI. I have two tables 'usr' and 'opinion' with a one to many relationship, the 'uid' in the 'opinion' table is a foreign key to the 'usr' table. The error from the code bellow suggests that the generated DELETE statement tries to use the table name in place of the foreign key field name. Or did I something wrong?
package Dl; use strict; use Data::Dumper; use base 'Class::DBI'; Dl->set_db(Main => "dbi:Pg:dbname=ab", "zby", ***); package Dl::Usr; use base 'Dl'; __PACKAGE__->table('usr'); __PACKAGE__->columns(All => qw/uid nick/); __PACKAGE__->sequence('usr_uid_seq'); __PACKAGE__->has_many(opinions => 'Dl::Opinion'); package Dl::Opinion; use base 'Dl'; __PACKAGE__->table('opinion'); __PACKAGE__->columns(All => qw/opid uid descr/); __PACKAGE__->sequence('opinion_opid_seq'); __PACKAGE__->has_a(uid => 'Dl::Usr'); package Main; my $user = Dl::Usr->create({nick => 'iwiiw'}); $user->delete; __OUTPUT__ usr is not a column of Dl::Opinion at /usr/local/share/perl/5.8.2/Clas +s/Trigger.pm line 51
perl version 5.8.2, Class::DBI version 0.95

Replies are listed 'Best First'.
Re: field names and Class::DBI
by bart (Canon) on Feb 19, 2004 at 16:44 UTC
    Add a third parameter, the field name in the other table, in the has_many() call.
    package Dl::Usr; __PACKAGE__->has_many(opinions => 'Dl::Opinion', 'uid');
      Thanks! This worked.

      Just to clarify. The documentation says:

      When setting up the relationship we examine the foreign class's has_a() declarations to discover which of its columns reference our class. If no such declarations are set up, or none match, we assume that it is linking to us via a column named after the moniker() of our class. If this is not true you can pass an additional third argument to the has_many() declaration stating which column of the foreign class references us.
      In my case the other table does have the has_a() declaration - so it should work the way I wrote.
        No... don't forget that has_many() and has_a() are actually method calls, not declarations... so they are executed in the order that they are in the source code. The has_many() call comes first, and at that time, the has_a() call hasn't happened yet.

        If you were to reorder your source code so that the has_a() call comes first, then it would indeed have to work.

        So, what happens now? Class::DBI makes a bad guess, it uses the "moniker" of the class name that has the has_many() call, for the field name for the remote table. In your case, that is "usr", derived from the class name "Dl::Usr".