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:
type
does not matter)type
= 'bundle')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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With