[Dbix-class] New cookbook recipe: inheriting from result classes
Sebastian Willert
willert at gmail.com
Sat Jun 24 02:29:06 CEST 2006
Hi all,
as promised on #dbix-class earlier today, I wrote some POD to explain
how one can inherit from result classes (this approach works for the
current dev releases only).
Feel free to edit, criticize, share and include anywhere.
Cheers,
Sebastian
---
=head1 NAME
DBIx::Class::Manual::Cookbook - Miscellaneous recipes
=head1 RECIPES
=head2 Inheritance
=head3 Upgrading result source classes
In some edge cases it might be useful (or even necessary if enforced
by local policies) to use a class hierarchy instead of a monolithic
result
source class.
In this recipe we will assume you have lightweight schema but need to
pull in some very heavy or inconvenient stuff for some perspectives on
your data. You wouldn't want them in your bases sources so we are just
going to create a plain schema at first
package Foo::Schema::Recipe;
use base 'DBIx::Class';
__PACKAGE__->load_components("PK::Auto", "Core");
__PACKAGE__->table("recipe");
__PACKAGE__->add_columns("id", "name", "description");
__PACKAGE__->set_primary_key("id");
__PACKAGE__->has_many
( ingredients => qw/Foo::Schema::Ingredients/ => qw/recipe/);
package Foo::Schema::Ingredient;
use base 'DBIx::Class';
__PACKAGE__->load_components("PK::Auto", "Core");
__PACKAGE__->table("ingredient");
__PACKAGE__->add_columns( "id", "recipe", "name", "quantity" );
__PACKAGE__->set_primary_key("id");
__PACKAGE__->belongs_to( recipe => qw/Foo::Schema::Recipe/ );
package Foo::Schema;
use base 'DBIx::Class::Schema';
__PACKAGE__->load_classes( qw/Recipe Ingredient/ );
1;
Now for the trickier part: inheriting from the schema classes has a
few caveats but lets get the boilerplate code out of the way first
(I've included C<Log::Log4perl> so you get an idea what I meant
with inconvenient, by the way).
package Bar::Recipe;
use base qw(Foo::Schema::Recipe);
use Log::Log4perl;
my $log = Log::Log4perl::get_logger( __PACKAGE__ );
So far, we didn't do anything unexpected, but C<DBIx::Class::Schema>
doesn't know anything about our new class. First of all we will have to
get a clone of the original source table class. Just setting the table
attribute again will achieve this.
__PACKAGE__->table( __PACKAGE__->table );
Then we will have to declare a distinct moniker for our subclass. If
we don't do this, C<Bar::Recipe> will override all
C<Foo::Schema::Recipe>
result sets which can be desirable for quick'n'dirty hacks but is not
advisable otherwise.
__PACKAGE__->source_name( 'HeavyRecipe' );
Finally we are all set to muck about the classes inner working to our
hearts content.
__PACKAGE__->has_many
( Ingredients => qw/Bar::Ingredient/ => qw/recipe/);
Writing C<Bar::Ingredient> is left as an exercise to the reader. The
last thing to do is load the new classes into a schema. This can be
done in a standard way trough inheriting from C<Foo::Schema> or at
run-time via:
$schema->load_classes({ Bar => [qw( Recipe Ingredient )] });
=cut
More information about the Dbix-class
mailing list