[CDBI] Normalization

Eamon Daly edaly at nextwavemedia.com
Tue Nov 15 18:32:06 GMT 2005


Yep, that's exactly what I was looking for. Thanks!

I generalized it out in a fairly kludgy fashion for the
archives to tear apart:

package My::Foo;
__PACKAGE__->set_up_table('foo');
__PACKAGE__->has_a(bar_id, 'My::Bar');

My::Foo->automap_columns;

sub automap_columns {
    my $package = shift;
    my $regex = shift || 's/_id$//';
    my %columns;

    for ($package->columns) {
        my $col = $_;
        $columns{$_}++ if eval "\$col =~ $regex";
    }

    for ($package->primary_columns) {
        delete $columns{$_};
    }

    foreach my $col_id (keys %columns) {
        my $col = $col_id;
        eval "\$col =~ $regex";
        eval <<EOF;
sub $col {
  my \$ret = shift->$col_id->$col;
  warn 'Column $col is read-only (maybe you meant $col_id?)' if defined 
shift;
  \$ret;
}
EOF
    }
}

This magically creates subs like:

sub bar { shift->bar_id->bar; }

for any non-PK column. By default, the regex used is
's/_id$//', but you could also specify a regex such as
's/_id$/_name/' like this:

My::Foo->automap_columns('s/_id$/_name/';

to create subs like:

sub bar_name { shift->bar_id->bar_name; }

____________________________________________________________
Eamon Daly



----- Original Message ----- 
From: "Matt S Trout" <dbix-class at trout.me.uk>
To: "Eamon Daly" <edaly at nextwavemedia.com>
Cc: <ClassDBI at svr02.digitalcraftsmen.net>
Sent: Monday, November 14, 2005 7:16 PM
Subject: Re: [CDBI] Normalization


> On Mon, Nov 14, 2005 at 05:38:19PM -0600, 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:
>>
>> my $bar_id = My::Foo->bar_id   # id
>> my $bar_value = My::Foo->bar   # value
>>
>> This gets me halfway there:
>>
>> package My::Bar;
>> __PACKAGE__->set_up_table('bar');
>>
>> package My::Foo;
>> __PACKAGE__->set_up_table('foo');
>> __PACKAGE__->has_a(bar_id, 'My::Bar');
>>
>> and elsewhere:
>>
>> my $bar_id = My::Foo->bar_id           # id
>> my $bar_value = My::Foo->bar_id->bar   # value
>>
>> but like I said, I'd really prefer to just say My::Foo->bar.
>> I'm sure it's trivial, but I just can't find the right
>> technique.
>
> sub bar { shift->bar_id->bar; }
>
> Class::DBI has method proxy stuff, but only in the might_have
> relationship.
>
> Under DBIx::Class you could just do
>
> __PACKAGE__->has_a('bar_id', 'My::Bar', undef, { proxy => 'bar' });
>
> You could probably make your own subclass of ::HasA that does the same for
> Class::DBI ...





More information about the ClassDBI mailing list