Re: [CDBI] Normalization

[prev] [thread] [next] [Date index for 2005/11/15]

From: Eamon Daly
Subject: Re: [CDBI] Normalization
Date: 18:32 on 15 Nov 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@xxxxx.xx.xx>
To: "Eamon Daly" <edaly@xxxxxxxxxxxxx.xxx>
Cc: <ClassDBI@xxxxx.xxxxxxxxxxxxxxxx.xxx>
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 ...


_______________________________________________
ClassDBI mailing list
ClassDBI@xxxxx.xxxxxxxxxxxxxxxx.xxx
http://lists.digitalcraftsmen.net/mailman/listinfo/classdbi

[CDBI] Normalization
Eamon Daly 23:38 on 14 Nov 2005

Re: [CDBI] Normalization
William Ross 00:50 on 15 Nov 2005

Re: [CDBI] Normalization
Matt S Trout 01:16 on 15 Nov 2005

Re: [CDBI] Normalization
Eamon Daly 18:32 on 15 Nov 2005

Generated at 21:49 on 21 Nov 2005 by mariachi v0.52