Как я могу смоделировать отношения is-a с DBIx :: Class? - PullRequest
4 голосов
/ 31 июля 2010

Со следующими (упрощенными) определениями таблиц MySQL:

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;

Будучи новичком в DBIx :: Class , я хотел бы смоделировать отношения наследования между объектами базы данных (оба являются компьютерами и принтерами), но с предоставленным типом отношения own_to это кажется неудобным Поскольку связь с базовым классом не является скрытой, поэтому все равно необходимо вручную создавать сущности для обоих классов, и доступ к атрибутам базового класса в производных классах отличается от доступа к их собственным атрибутам.

Есть ли элегантное решение, которое позволило бы мне сказать:

$printer = $printer_rs->create({purchase_date => $date, is_duplex => 0});

или (в строке извлеченного принтера):

$date = $printer->purchase_date;
$duplex = $printer->is_duplex;

1 Ответ

6 голосов
/ 31 июля 2010

Вы можете использовать атрибут proxy в отношении для включения средств доступа - он задокументирован в add_relationship из DBIx :: Class :: Relationship :: Base , и вы можете использовать его с belongs_to как:

__PACKAGE__->belongs_to(
  'item' => 'MyApp::Schema::Item',
  'item_id',
  { proxy => [ qw/purchase_date/ ] }
);

, что сделает все ваши объекты Принтера имеющими purchase_date средства доступа, которые ссылаются на связанный объект Item.

Что касается создания, вы не можете сделать это без переопределения new_result, что на самом деле довольно просто. Вам просто нужно воспользоваться поведением создания из, чтобы включить

->create({
  is_duplex => 1,
  purchase_date => $dt,
})
* +1015 * в
->create({
  is_duplex => 1,
  item => {
    purchase_date => $dt,
  },
})

Или вы можете просто навязать своим пользователям сведения о том, какие столбцы есть в item, и попросить их предоставить этот хэш-адрес напрямую;)

...