With the following (simplified) MySQL table definitions:
create table items (
item_id int unsigned auto_increment primary key,
purchase_date date
) engine = innodb;
create table computers (
item_id int unsigned primary key,
processor_type varchar(50),
foreign key item_fk (item_id) references items (item_id)
on update restrict on delete cascade
) engine = innodb;
create table printers (
item_id int unsigned primary key,
is_duplex boolean,
foreign key item_fk (item_id) references items (item_id)
on update restrict on delete cascade
) engine = innodb;
Being new to DBIx::Class, I would like to model an inheritance relationship between database entities (computers and printers both being items), but with the provided belongs_to relationship type, this seems to be awkward, because the association with the base class is not hidden, so one must still manually create entities for both classes, and access to base class attributes in the derived classes is different from accessing their own attributes.
Is there an elegant solution which would allow me to say:
$printer = $printer_rs->create({purchase_date => $date, is_duplex => 0});
or (on a fetched printer row):
$date = $printer->purchase_date;
$duplex = $printer->is_duplex;
?
You can use the proxy
attribute on a relationship to enable the accessors -- it's documented in add_relationship
of DBIx::Class::Relationship::Base and you can use it with belongs_to
like:
__PACKAGE__->belongs_to(
'item' => 'MyApp::Schema::Item',
'item_id',
{ proxy => [ qw/purchase_date/ ] }
);
which will make all of your Printer objects have purchase_date
accessors that refer to the associated Item object.
As for create, you can't do it without overriding new_result
, which is actually pretty easy. You just have to take advantage of the create-from-related behavior to turn
->create({
is_duplex => 1,
purchase_date => $dt,
})
into
->create({
is_duplex => 1,
item => {
purchase_date => $dt,
},
})
Or you could just foist the knowledge of what columns are in item
off on your users and have them provide that hashref directly ;)