この記事内容の、納得いかない部分の修正案を考えました。
この記事をそのまま使うと変なんなっちゃうので、下記も読んでみてください。
続、Tengを使いたくて(今回はDB周りの話はありません)
Tengって?
分類すると、ORマッパーっていうものだそうです。
何ができるのかというと、データベースを軽いタッチで使えるようになるとのこと。
今まで(未だに?)素のDBIでデータベース操作していましたが、以前からDBICとかDBIx::Skinnyとかに興味ありながらも新しいものを避けてきたなかなか触る機会がなかったのでした。
でもやっぱり早く作れたほうがいいよね、ということで、思い切ってやってみようと思ったのでした。
単純に使う場合は、情報がネット上に割とあるので困らないのですが。
複数のテーブルがある場合は操作も複雑になるし、その場合はサブルーチンが増えるので、ファイル1枚じゃつらいよね、ということで試行錯誤しました。
複数のファイルに処理を分けたい
いまだにPerl初級者の域を全く出ない私なので、なかなか手こずりました。
メインになるファイルの下層に、処理を内容ごとに切り分けた関数群のファイルを置いて、そこからエクスポートして、メイン側のファイルでインポートする、とか。何やら名前空間がぐちゃぐちゃになりそうな。
結局うまくいかなかったんですが。
自分流、現時点での結論
正直言ってベストかどうか大いに疑問を感じているので、真似しないほうがいいと思います。
ファイル構成は、
/lib/MyApp
/lib/MyApp/Model.pm ----- Model本体
/lib/MyApp/Model/Table1.pm ----- Table1の処理用
/lib/MyApp/Model/Table2.pm ----- Table2の処理用
/lib/MyApp/Model/DB/MySQL.pm ----- Teng読み込み用
/lib/MyApp/Model/DB/MySQL/Schema.pm ----- Tengのスキーマ
package MyApp::Model::DB::MySQL;
use strict;
use warnings;
use utf8;
use parent 'Teng';
1;
これだけ。。。
万が一自前のメソッド足したいときはここに。
package MyApp::Model;
use strict;
use warnings;
use utf8;
use DBI;
use MyApp::Model::DB::MySQL;
sub new {
my $pkg = shift;
my $teng = MyApp::Model::DB::MySQL->new({
connect_info => ['DBI:mysql:database=db_name;host=localhost;', 'db_user', 'db_pass', {mysql_enable_utf8=>1}]
});
bless {
'TENG' => $teng
}, $pkg;
}
1;
ここもこれだけ。
共通で使いそうな処理はこのMyApp::Model
に書く。
package MyApp::Model::Table1;
use strict;
use warnings;
use utf8;
use parent 'MyApp::Model';
sub get_data{
my $self = shift;
#処理
#my $row = $self->{'TENG'}->single(......); 的な
return { 'data' => 'data' };
}
1;
という感じにしました。
perent
を使ったので、MyApp::Model
でnew
した内容が引き継がれるので、全部のファイルにDBの接続用のヤツを書かなくて済むのでよかった、みたいな雰囲気です。
きっともっとスマートな方法があるんでしょうね。
なんでMyApp::Model::DB::MySQLを分けたの?
なんとなく自分的に、Modelは「データを出し入れする担当」、Controllerは「リクエストを捌いたり、レスポンス内容をViewに渡す担当」というイメージがあって、データベース関連以外にもデータを扱うのはModelにやってほしいな、と感じています。
たとえば天気予報のデータをどこかのサイトから持ってきて整形してController側に渡す、とか。
なので、DBだけではないので、混ざっちゃうとゴチャゴチャしちゃうじゃん、という単純な発想でした。
DBにしても、MySQL以外のものを合わせて使う場合もあるでしょうし。MongoDBとか。
ひとまず、今回はこの構成で進めて行こうと思っています。