たまにはいつも使ってるのとは違う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する。
この項、いろいろ間違っているかも。