DBIx::Class::FromSledgeやってみました。
DBICやらねばやらねばと思っていたところで、DBIx::Class::FromSledgeというモジュールがリリースされたとの事で折角なのでDBICも合わせてやってみました。
DBIx::Class::FromSledgeは、create_from_sledge、update_from_sledgeの二つのメソッドが有り、この人達にPagesオブジェクトを投げると良い感じにinsert,updateしてくれます。
配置
`-- SampleApp |-- Config | |-- _common.pm | `-- _test.pm |-- Config.pm |-- DB | `-- Table01.pm |-- DB.pm |-- Pages | `-- Root.pm `-- Pages.pm
DB.pmがスキーマで、DB/Table01.pmがテーブルのクラスです。
まずこれら2つの中身を。
DB.pm
package SampleApp::DB; use base qw(DBIx::Class::Schema); use SampleApp::Config; __PACKAGE__->connection(SampleApp::Config->instance->datasource); __PACKAGE__->load_components(qw(FromSledge)); __PACKAGE__->load_classes(qw(Table01)); 1;
DB/Table01.pm
package SampleApp::DB::Table01; use strict; use base qw(DBIx::Class); __PACKAGE__->load_components(qw( FromSledge PK::Auto Core )); __PACKAGE__->table('table01'); __PACKAGE__->add_columns(qw(id name registed timestamp)); __PACKAGE__->set_primary_key('id'); 1;
Schemaという概念がCDBIとかなり違いますでしょうか。
load_componentsにそれぞれFromSledgeを足し込んでます。
ちなみにtable01の構造
table01
mysql> desc table01; +-----------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+------------------+------+-----+---------+----------------+ | id | int(10) unsigned | | PRI | NULL | auto_increment | | name | varchar(255) | YES | | NULL | | | registed | datetime | YES | | NULL | | | timestamp | timestamp(14) | YES | | NULL | | +-----------+------------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec)
以上で準備が出来ましたので、insert・updateするPagesを作りました。
$self->modelにスキーマをsetしてます。
Pages/Root.pm
package SampleApp::Pages::Root; use strict; use base qw(SampleApp::Pages); use Sledge::Plugin::Validator; use SampleApp::DB; use Time::Piece::MySQL; use Data::Dumper; __PACKAGE__->mk_accessors(qw(model)); __PACKAGE__->register_hook( BEFORE_DISPATCH => sub { my ($self) = @_; $self->model(SampleApp::DB->connect); }, ); sub now { Time::Piece->new->mysql_datetime }
そして、いよいよ登録・更新するメソッドです。
まずバリデートメソッド
sub valid_index { my ($self) = @_; return unless $self->is_post_request; $self->valid->err_template('index'); $self->valid->check( name => [qw(NOT_NULL), [qw(LENGTH 1 255)]], ); }
DBIC::FromSledgeの方ではValidatorオブジェクトからカラムを決定するようです。
$page->valid->{PLAN}->{$col}
つまりvalidation対象のカラムがPagesから引っこ抜かれると。なるほど。
そして、バリデートをめでたく抜けて、insert or update。
sub dispatch_index { my ($self) = @_; if ($self->is_post_request) { if (my $id = $self->r->param('id')) { $self->model->resultset('Table01')->find($id)->update_from_sledge($self); } else { $self->model->create_from_sledge('Table01', $self, {registed => now}); } } else { if (my $id = $self->r->param('id')) { $self->tmpl->param(obj => $self->model->resultset('Table01')->find($id)); } } my $itr = $self->model->resultset('Table01')->search({}); $self->tmpl->param(table01 => $itr); } 1;
create_from_sledge時は決め打ちでregistedにnowを指定してます。
実行後
mysql> select * from table01; +----+------------------+---------------------+----------------+ | id | name | registed | timestamp | +----+------------------+---------------------+----------------+ | 1 | ネプチューンマン | 2007-01-11 16:52:00 | 20070111171405 | | 2 | 喧嘩マン | 2007-01-11 17:11:02 | 20070111171102 | +----+------------------+---------------------+----------------+
無事入りました!
未使用時との比較
例ではテーブルのカラムが少ないのであまりよしくないですが、従来と比較するとかなりすっきりしそうです。
※valid_xxxは前提で。
従来
Table->create({ mail => $self->r->param('mail'), tel => $self->r->param('tel'), fax => $self->r->param('fax'), zip => $self->r->param('zip'), stat => 1, registed => Time::Piece->new->mysql_datetime, );
という感じで書いていましたが、
FromSledge
$schema->create_from_sledge('Table', $self, {stat => 1, registed => Time::Piece->new->mysql_datetime});
すっきり!!