erstellt von max, am 27.05.2008 00:18

so, seit heute unterstuetzt webtek single und concrete table inheritance.

single table inheritance (weitere infos)


create table text (
   id int auto_increment,
   class varchar(100),
   text text,
   comment text,
   PRIMARY KEY (id)
);

man sieht hier, dass es eine column class gibt, welche die model-klasse definiert. hier noch der noetige perl code. wichtig ist, dass die subklassen jeweils in eigenen dateien stehen (sonnst kommt der WebTek::Loader durcheinander). mit den (optionalen) PROPERTIES funktionen kann man die models validieren.

MyApp/Model/Text.pm

use base qw( WebTek::Model );

sub PROPERTIES { 'text' => '.' }

MyApp/Model/Comment.pm

use base qw( MyApp::Model::Text );

sub PROPERTIES { 'comment' => '.' }

nun funktioniert folgender code:

> app->Model->Text->new_default('text'=>'text')->save
Model::Model::Text=HASH(0x....)
> app->Model->Comment->new_default('comment'=>'comment')->save
Model::Model::Comment=HASH(0x....)
> app->Model->Text->find_one(id=>1)
Model::Model::Text=HASH(0x....)
> app->Model->Text->find_one(id=>2)
Model::Model::Comment=HASH(0x....)

concrete table inheritance (weitere infos)


create table posts (
   id int auto_increment,
   text text,
   PRIMARY KEY (id)
);
create table comment (
   id int auto_increment,
   text text,
   PRIMARY KEY (id)
);

hier gibt es zwei tabellen (zusaetzlich muss noch sichergestellt werden, dass diese tabellen nicht die gleichen ids verwenden, entweder auto_increment bei einer tabelle erst bei 1000000 beginnen lassen (danke fuer den tip von adrian), oder irgendwas mit einer sequence). hier wieder der noetige perl code. weiters zu beachten ist, dass man bei den subclassen zusaetzlich zur superklasse (hier z.b. MyApp::Model::Text) noch das WebTek::Model in das @ISA array aufnimmt (sonnst initialisiert der WebTek::Loader das model nicht).

MyApp/Model/Text.pm

sub find_one_factory {
   my $class = shift;
   return app->Model->Post->find_one(@_)
      || app->Model->Comment->find_one(@_);
}
sub find_factory {
   my $class = shift;
   return app->Model->Post->find(@_)
      || app->Model->Comment->find(@_);
}
sub where_factory {
   my $class = shift;
   return app->Model->Post->where(@_)
      || app->Model->Comment->where(@_);
}
sub count_factory {
   my $class = shift;
   return app->Model->Post->count(@_)
      || app->Model->Comment->count(@_);
}
sub count_where_factory {
   my $class = shift;
   return app->Model->Post->count_where(@_)
      || app->Model->Comment->count_where(@_);
}

#... add more general methods
sub foo { ... }
sub text_as_uppercase { ... }
sub whatever { ... }

MyApp/Model/Post.pm

use base qw( MyApp::Model::Text WebTek::Model );

MyApp/Model/Comment.pm

use base qw( MyApp::Model::Text WebTek::Model );

so, dass ist jetzt viel komplizierter, aber man hat dafuer eine saubere trennung der datenbank. und so kann das dann verwendet werden:

> app->Model->Post->new_default('text'=>'text')->save
Model::Model::Post=HASH(0x....)
> app->Model->Comment->new_default('text'=>'comment')->save
Model::Model::Comment=HASH(0x....)
> app->Model->Text->find_one_factory(id=>1)
Model::Model::Post=HASH(0x....)
> app->Model->Text->find_one_factory(id=>2)
Model::Model::Comment=HASH(0x....)
> app->Model->Text->find_one_factory(id=>2)->text_as_uppercase
COMMENT

class table inheritance (weitere infos)

gibts nicht, ist mir zu kompliziert... :)

Neuen Kommentar schreiben: