[CDBI] Normalization

William Ross will at spanner.org
Tue Nov 15 00:50:08 GMT 2005

On 14 Nov 2005, at 23:38, Eamon Daly wrote:

> Okay, so now I'm a touch confused. Suppose I have a table
> "foo" with columns "foo_id" (the PK) and "bar_id". Table
> "bar" contains columns "bar_id" (the PK) and "bar". How do I
> define the relationship between the tables so that these
> both work:

This is a common problem, and there are various solutions, but I  
think the official best one is to use accessor_name_for in your base  
class, roughly like so:

   sub accessor_name_for {
     my ($class, $column) = @_;
     $column =~ s/_id$//;
     return $column;

The docs for accessor_name_for are there, but a bit unhelpful at the  
moment, and because of a bug in the latest cdbi you should also add  

   sub mutator_name_for { return shift->accessor_name_for(@_) }

which ought to be harmless when the bug is fixed.

I don't actually use this - i prefer just to name each relationship  
column with the moniker of the foreign class* - but I believe that  
the column name is changed throughout, and you should always refer to  
it in perl as just 'bar':

__PACKAGE__->columns(Essential => qw(foo_id bar_id));
__PACKAGE__->has_a(bar => 'My::Bar');

however, you'll still need to call it 'bar_id' in any any custom SQL  
you write, unless (I think) you use shortcuts like __ESSENTIAL__, as  
one should but I never do.

note that your primary key column will also be shortened to 'foo',  
which probably won't matter unless you don't want to rely on the  
default stringification: you may end up having to write something  
like [% foo.foo %] to get at the key value.



* users of cdbi seem to divide into the database-first and the perl- 
first, and I guess this puts me firmly in the latter camp.

More information about the ClassDBI mailing list