Subscribed unsubscribe Subscribe Subscribe

Kentaro Kuribayashi's blog

Software Engineering, Management, Books, and Daily Journal.

Data::Model事始め

たまにはいつも使ってるのとは違うORMを使ってみようってんで、id:yappoさん作のData::Modelを使ってみました。その特徴である、独立したカラム定義や、そのことによる柔軟なエイリアス、inflate/deflateの仕組み、透過キャッシュなど、とてもいい感じだなーと思いました。

……が、Active Recordパターン脳としては、たとえばRow クラスにメソッドを追加 - JPerl Advent Calendar 2009にあるような、schema定義の中にadd_methodしておのおののテーブル定義の中にロジックを書いていくのは、なんだか見通しが悪いという感じが……。どうにかならないのかなーってんでソースを見てみたら、どうにかなっていました。申し分けございません。

たとえば、Userというモデルに対して、以下のような定義を行うとして、

package MyApp::Model;

# (中略)

install_model User => schema {
    key    'id';
    columns qw(id name);
};

このUserというモデルのオブジェクトが作成される時に、内部では、Data::Model::Rowを継承関係に持つMyApp::Model::User->newが走るので、つまりMyApp::Model::Userに、Active Recordパターンでいうところのドメインロジックを書けばよさそうだ。

package MyApp::Model::User;

sub hello {
    my $self = shift; #=> rowオブジェクトがわたされる
    warn 'こんにちはこんにちは! 僕の名前は' . $self->name . 'だよ';
}

1;

こうしておけば、add_methodしなくても、以下のように$user->helloと呼べる。

my $user = MyApp::Model->new->lookup(User => 1); # idが1のユーザ
$user->hello;

ただし、この例のMyApp::Model::Userを次のようにしてあらかじめuseしておかなけらばならないぽい?

package MyApp::Model;

# (中略)

use MyApp::Model::User;

# (中略)

install_model User => schema {
    key    'id';
    columns qw(id name);
};

あるいは、MyApp::Modelをuseしているスクリプトかなんかの側でMyApp::Model::Userをuseする。

この項、いろいろ間違っているかも。