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
あとで試してみよ。