DBIx and inheritance in Perl
dbix-class, inheritance, perl
Solution
The usage of `resultset_attributes` is not recommended. You should implement a result set class for `Product` with methods `bundle_products` and `general_products`:
package My::Schema::ResultSet::Product;
use base 'DBIx::Class::ResultSet';
sub bundle_products { shift->search({ type => 'bundle' }); }
sub general_products { shift->search({ type => 'general' }); }
Then you can search specific products like this:
$schema->resultset('Product')->bundle_products->all;
$schema->resultset('Product')->general_products->all;
See the documentation of resultset_attributes.
Also have a look at DBIx::Class::DynamicSubclass. It adds some useful features when subclassing results.
Problem
I'm currently trying to implement the following scenario with DBIx: The table products contains "general products" and "bundle products" (bundle products are collections of general products): ``` package Product; use base 'DBIx::Class::Core'; __PACKAGE__->table("products"); __PACKAGE__->add_columns( "productId", { data_type => "varchar", is_nullable => 0, size => 10}, "name", { data_type => "varchar", is_nullable => 1, size => 150}, "type", { data_type => "enum", default_value => "general", extra => { list => ["general", "bundle"], }, is_nullable => 0, }); ``` As you can see, wether the product is a general product or a bundle product is saved in the column type. Now I would like to encapsulate this information in the class identity: I would like to have following classes: - Product (`type` does not matter) - BundleProduct (`type` = 'bundle') - GeneralProduct (`type` = 'general') I wrote: ``` package BundleProduct; use base 'Product'; __PACKAGE__->resultset_attributes({ where => { 'type' => 'bundle' } }); 1; ``` and ``` package GeneralProduct; use base 'Product'; __PACKAGE__->resultset_attributes({ where => { 'type' => 'general' } }); 1; ``` But when executing ``` my @allProducts = $schema->resultset('BundleProduct')->all; ``` all general products are fetched. Although the resulting objects are of instance `BundleProduct`, the generated SQL contains the WHERE-condition of the class `GeneralProduct` (`type` = 'general'). Even worse: If I try to fetch a `Product` (base class of `BundleProduct` and `GeneralProduct`) the condition `type` = 'general' is applied, too! It seems that the definition within `GeneralProduct` overwrites all other definitions. What is wrong with my design?