FormValidatorとDBIx::Class::WebFormの組み合わせはいい。
Scaffoldなどではすでに使われているのだけど、FormValidator::Simple(Data::FormValidator)とDBIx::Class::WebForm(Class::DBIの場合はClass::DBI::FromForm)、この組み合わせはヤバいね。非常に楽ができてしまう。
研究中のCatalystアプリの部分だけど、タイトルと、内容、時間(年〜秒まで6つのフォーム)があって、それをDBに入れる場合、
my $result = $c->form( title=>[qw/NOT_BLANK/], text=>[qw/ANY/], {created_on=>[qw/d_year d_month d_day d_hour d_min d_sec/]}=>[qw/NOT_BLANK DATETIME/] ); $c->detach('default') if $c->form->has_error; my $entry = MyApp::Model::DBIC::Entry->create_from_form($result);
これで確認も保存もできてしまう。 ちなみにテーブル定義は↓です。
create table entry( id int unsigned not null auto_increment, title varchar(250) not null, text text, created_on datetime not null );
アップデートの場合は、
my $entry = MyApp::Model::DBIC::Entry->find($c->req->params->{entry}); $c->req->params->{id}=$c->stash->{entry}->id;#データベース上はIDなので my $result = $c->form( id=>[qw/ANY/], title=>[qw/NOT_BLANK/], text=>[qw/ANY/], {created_on=>[qw/d_year d_month d_day d_hour d_min d_sec/]}=>[qw/NOT_BLANK DATETIME/] ); $c->detach('default') if $c->form->has_error; $entry->update_from_form($result);
こうやって書ける。
WebFormをLoaderと同時に使う場合(CatalystのヘルパーでModelクラスをつくった時など)のWebFormの追加の方法は、
__PACKAGE__->config( dsn => '**', user => '**', password => '**', additional_base_classes => 'DBIx::Class::WebForm', options => {}, relationships => 1 );
で行ける模様。
ValidatorとO/Rマッパーの連携のすばらしさを実感。
コメント
Catalyst::Plugin::FVS
のほうにはちょろっと書いておいたんですが、
そのへん本体のドキュメントに書くの忘れてましたね…
DATETIME型はちょっと特殊に扱えるようになってます。
$result->valid('created_on');
で返すデータはオプションで
datetime_class => 'DateTime' のようにして
DateTimeとかTime::Pieceのオブジェクトにもできます。
DateTimeの場合は
time_zone => 'Asia/Tokyo'
とかも。
なんにも指定しないと、
2005-11-25 00:00:00
みたいな形で返します。
Class::DBI::Plugin::DateTime
みたいなの使う場合にいいかも。
フォームにないデータを一緒に
*_from_form で突っ込みたい場合は、
$result->record('key')->data('hoge');
とかやって強制的に新しいキーとデータ作成できます。
なんでシングルキーでANY使ってるのかなーと
最初思ったんですけど
たぶん無理矢理キー作りたいってことですよね?
あとNOT_BLANKキーは複数キー用になってないです。
複数キー用に ALL とか作っておきますね。
全体的にDoc不足ですね。反省。
投稿者: kato | 2005年11月27日 00:53
katoさん、いつもながら参考になります。
datetime_classはみてませんでしたが、inflate/deflateとあわせるといい感じですね。DBIx::Classのinflate/deflateは
DBIx::Class::InflateColumnのinflate_columnメソッドでinflateだけ試してます。
> なんでシングルキーでANY使ってるのかなーと
っていうのはまさにその通りで、
$result->record('key')->data('hoge');
も使えそうですが
key=>[qw/ANY/],
の方が直感的かなぁと思いました。
投稿者: かぜぶろ | 2005年11月27日 01:21
DBIx::Class::WebForm では?
投稿者: tokuhirom | 2005年11月28日 15:14
うわぁぁぁ。素で気づかなかった。
tokuhirom様、ありがとうございます。
投稿者: かぜぶろ | 2005年11月28日 17:08