Amon2でModel作ってControllerから呼ぶ
2014年5月7日
MVCが良いか悪いかは兎も角、、
ViewとControllerしかないので、Modelを作ってみます。
Amon2のサンプル的なやつだと、Controllerから直接dbを叩いてるようなのがよくあるんですけど、Controller肥大化を避ける意味でも。
(Catalystで言うところの、Catalyst::Model::DynamicAdaptor(MultiAdaptor)的な動きが個人的には好みですw)
以下、個人的メモ。
MyApp::Modelってプラグインを作成。
package MyApp::Model; use strict; use warnings; use File::Basename; use lib sprintf("%s/lib", dirname(__FILE__)); use Amon2::Util; use Module::Find; sub init { my ($class, $c) = @_; my $model = undef; my @model = usesub MyApp::Model; # MyApp::Model::以下をuse for ( @model ) { my $name = $_; $name =~ s/^MyApp::Model:://; $model->{ $name } = $_->new({ config => $c->config }) if $_; } # $c->modelを追加 Amon2::Util::add_method( $c, 'model', sub { $_[0]->{'model'} ||= $model; } ); } 1;
これでMyApp::Model以下のモジュールをnewしたものが、$c->model->{‘xx’}で呼べるはずです。
呼ばれるやつは下。
package MyApp::Model::User; use strict; use warnings; use Object::Simple -base; has [qw/config/]; sub find_name { my ( $class, $args ) = @_; return 'hogehoge'; } 1;
コンストラクタは、Object::Simpleを使ってますけど、
Class::Accessor::Lite(Fast)でも、Mooseでも好きなやつで。
上で作ったプラグインを追加
package MyApp; use strict; use warnings; use utf8; our $VERSION='0.01'; use 5.008001; use parent qw/Amon2/; __PACKAGE__->load_plugin('+MyApp::Model'); # Enable project local mode. __PACKAGE__->make_local_context(); 1;
先頭の+をつけない場合は、Amon2::Plugin::***になってしまいます。
今回は自分で勝手に作ったやつなんで、先頭に+をつけます。
Controllerから叩く。
package MyApp::Web::C::Root; use strict; use warnings; use utf8; sub index { my ( $class, $c ) = @_; my $user_name = $c->model->{'User'}->find_name({ user_id => 1234 }); return $c->render('index.tx'); } 1;
DBの接続(切断)まわりは検討中。。
多分、この辺りかな?
package MyApp::Web; __PACKAGE__->add_trigger( BEFORE_DISPATCH => sub { my $c = shift; # DB接続 }, AFTER_DISPATCH => sub { my ( $c, $res ) = @_; # DB切断 }
追記
cpanにはまだ上がってないみたいですけど、githubにAmon2::Plugin::Modelがありました。。。
Amon2::Plugin::Model
あとで試してみよ。